<?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: Maxime Houle</title>
    <description>The latest articles on DEV Community by Maxime Houle (@maximehoule).</description>
    <link>https://dev.to/maximehoule</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%2F4038387%2F9c714ae0-1eaf-4f55-a2ac-ccffa6fe0d79.png</url>
      <title>DEV Community: Maxime Houle</title>
      <link>https://dev.to/maximehoule</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maximehoule"/>
    <language>en</language>
    <item>
      <title>Proving your agent did what it claimed: a receipts-based approach</title>
      <dc:creator>Maxime Houle</dc:creator>
      <pubDate>Sat, 25 Jul 2026 11:44:43 +0000</pubDate>
      <link>https://dev.to/maximehoule/proving-your-agent-did-what-it-claimed-a-receipts-based-approach-3app</link>
      <guid>https://dev.to/maximehoule/proving-your-agent-did-what-it-claimed-a-receipts-based-approach-3app</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Your agent said "done." A dependency bumped last week. You cannot actually prove the agent still does what it did before, because you have no record of what it did before. Here is how I started recording real runs and diffing every future run against them, at zero LLM cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  The moment this became my problem
&lt;/h2&gt;

&lt;p&gt;I merged a green Dependabot PR. Small patch bump on an MCP tool server, SemVer said safe, CI was green, I clicked the button.&lt;/p&gt;

&lt;p&gt;Three days later a user flagged that the agent was skipping a step it used to run. Nothing in my test suite caught it, because my "tests" were me running the agent by hand, reading the transcript, and deciding it looked right. The agent had told me "done" every single time. It was not lying on purpose. It just had no way to know, and I had no way to check.&lt;/p&gt;

&lt;p&gt;The real question underneath "how do I prove my agent did what it claimed" is this: compared to what? You cannot prove a run is correct if you have no honest record of a run that was correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the transcript is not proof
&lt;/h2&gt;

&lt;p&gt;The natural instinct is to re-read the transcript. That does not scale past a handful of runs, and worse, the transcript is the agent's own summary. If the agent says it wrote the file and it did not, the transcript still says it wrote the file.&lt;/p&gt;

&lt;p&gt;What you actually want is the ground truth: the exact tool calls it made, the arguments it passed, and the outputs it got back. Not the narration. The receipt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Record the run that worked
&lt;/h2&gt;

&lt;p&gt;The fix that finally held for me was boring in the best way. Record one real run while it is behaving. That capture becomes the baseline everything else is measured against.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;capture a real, known-good run of your agent&lt;br&gt;
reelier record -- node agent.js "onboard a new client"&lt;br&gt;
writes a recording: every tool call, args, and result&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The recording is not a mock and not a hand-written fixture. It is what the agent genuinely did, tool call by tool call. That is the receipt you were missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replay it, and diff against the baseline
&lt;/h2&gt;

&lt;p&gt;Now the useful part. When anything changes (a dependency bump, an MCP tool-server patch, a refactor), you replay the recorded run and diff the result against the original.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;replay the recorded tool behavior, no model calls&lt;br&gt;
reelier run --max-level 0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;compare this run against the recorded baseline&lt;br&gt;
reelier diff&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;--max-level 0 replays the recorded tool behavior without calling the LLM at all. That means the replay costs &lt;strong&gt;0 LLM tokens&lt;/strong&gt;. In reelier's own runs, 1,000 out of 1,000 replays came back byte-identical, which is what makes the diff trustworthy: if something changed, it changed because of your bump, not because the model felt different today.&lt;/p&gt;

&lt;p&gt;If the bump changed nothing, reelier diff is empty and you merge with confidence. If it changed a tool call, an argument, or a result, the diff shows you exactly what and where, before it reaches a user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assert on the steps that matter
&lt;/h2&gt;

&lt;p&gt;A full diff is great for a human. For CI you usually want to fail on specific things: this tool must be called, this argument must be present, this step must not disappear. Per-step asserts let you pin the parts of the run you actually care about, so a meaningful drift turns into a red check instead of a shrug.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wire it into the PR (the check Dependabot lacks)
&lt;/h2&gt;

&lt;p&gt;This is the piece Dependabot cannot give you. Dependabot tells you a version changed and that SemVer says it is safe. It does not tell you whether your agent still behaves the same. SemVer-safe is not behavior-safe.&lt;/p&gt;

&lt;p&gt;So put the replay on the pull request. A GitHub Action re-runs your recorded workflows against the bumped dependency and diffs them, and the check goes red on the PR when behavior drifts. Now "is this bump safe" has an answer you can read instead of a hope you carry into prod.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.github/workflows/agent-drift.yml (sketch)&lt;br&gt;
name: replay recorded runs against the bump&lt;br&gt;
run: reelier run --max-level 0 &amp;amp;&amp;amp; reelier diff --check&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Because the replay is 0 tokens, this runs on every Dependabot PR for free. The bump-check recipe walks through the full setup here: &lt;a href="https://www.reelier.com/docs/dependabot-bump-check" rel="noopener noreferrer"&gt;https://www.reelier.com/docs/dependabot-bump-check&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  An honest caveat about model upgrades
&lt;/h2&gt;

&lt;p&gt;One thing I want to be straight about: the 0-token story is for replaying recorded tool behavior, like dependency and MCP-tool bumps. If you are testing a model upgrade, you have to actually re-run against the new model, and that costs tokens, because the model is the thing you are checking. The record then diff pattern still applies, you just cannot do it for free in that case. Different problem, same discipline.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mental model that stuck
&lt;/h2&gt;

&lt;p&gt;Treat the agent's "done" as a claim, not a fact. A recorded run is the receipt that either backs the claim up or exposes it. Once every run has a receipt, "prove it" stops being a code-review argument and becomes a diff.&lt;br&gt;
reelier is MIT-licensed and open source, so you can read exactly how the record, replay, and diff work rather than trust a black box.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>mcp</category>
      <category>devops</category>
    </item>
    <item>
      <title>You Snapshot-Test Your UI. Your AI Agent's Workflows? Nothing. Here's the Fix (0 Tokens per Replay)</title>
      <dc:creator>Maxime Houle</dc:creator>
      <pubDate>Tue, 21 Jul 2026 20:10:03 +0000</pubDate>
      <link>https://dev.to/maximehoule/you-snapshot-test-your-ui-your-ai-agents-workflows-nothing-heres-the-fix-0-tokens-per-replay-fgj</link>
      <guid>https://dev.to/maximehoule/you-snapshot-test-your-ui-your-ai-agents-workflows-nothing-heres-the-fix-0-tokens-per-replay-fgj</guid>
      <description>&lt;p&gt;Your agent runs the same "pull the metrics, check the deploy, write the report" loop on a schedule. Every single run, the model re-derives those steps from scratch — at full token cost, with no guarantee it does the same thing twice.&lt;/p&gt;

&lt;p&gt;You'd never ship UI like that. You snapshot-test it. Your agent's workflows have no equivalent. 🫠&lt;/p&gt;

&lt;p&gt;That's the gap Reelier (github.com/seldonframe/reelier) fills: &lt;strong&gt;record a working run once, compile it to a SKILL.md, replay it deterministically at 0 tokens, and diff runs to catch drift&lt;/strong&gt; — with an exit code your CI understands.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers first, because you should demand them
&lt;/h2&gt;

&lt;p&gt;From the repo's published benchmark:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1,000/1,000 replays byte-identical&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 tokens per replay&lt;/strong&gt; (verified from run records — there's no model in the loop to bill)&lt;/li&gt;
&lt;li&gt;**48ms vs 2,842ms **against the agent doing the same work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the limits, stated just as plainly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Replay handles the deterministic core; &lt;strong&gt;judgment steps still need a model&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read-only by default&lt;/strong&gt; — writes never re-fire without --allow-writes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what a replay actually hands you back:&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;`▶ nightly-deploy-check (level 0, read-only)
  1. github.get_latest_deployment .... ok  4/4 asserts  31ms
  2. http.get ........................ ok  3/3 asserts  17ms

PASS  2 steps · 7/7 asserts · 0 tokens · 48ms
receipt: .reelier/runs/2026-07-21T06-00-12Z.json`
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A receipt 🧾, not a vibe. Let's build one. All commands work as-is in PowerShell and bash — one command per line, no &amp;amp;&amp;amp;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Install and init
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; reelier
reelier init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;reelier init&lt;/em&gt; looks for agent session history already on your machine — Claude Code, Codex, Windsurf, and OpenClaw all write sessions to disk — and offers to lift a replayable workflow out of work you've already paid for.&lt;/p&gt;

&lt;p&gt;No API key, no signup. Everything runs and stays local.&lt;/p&gt;

&lt;p&gt;Want to record fresh instead? Wrap any MCP server in Reelier's recording proxy and use your agent normally:&lt;br&gt;
&lt;code&gt;reelier mcp --wrap "npx -y @your/mcp-server"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every tool call and result flowing through the proxy gets captured. Or convert a specific past session directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;reelier from-session
reelier scan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2 — What a compiled SKILL.md looks like
&lt;/h2&gt;

&lt;p&gt;Compilation makes &lt;strong&gt;zero LLM calls&lt;/strong&gt; — it's a deterministic transform from the recording. Here's the shape (trimmed from a real recording; your field names will differ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Skill: nightly-deploy-check&lt;/span&gt;

Recorded from: claude-code session 2026-07-14
Replay level: 0 (deterministic, read-only)

&lt;span class="gu"&gt;## Steps&lt;/span&gt;

&lt;span class="gu"&gt;### 1. github.get_latest_deployment&lt;/span&gt;
args: { "repo": "acme/storefront", "env": "production" }
assert:
&lt;span class="p"&gt;  -&lt;/span&gt; status: ok
&lt;span class="p"&gt;  -&lt;/span&gt; type: result.sha == string
&lt;span class="p"&gt;  -&lt;/span&gt; regex: result.sha ~ ^[0-9a-f]{40}$
&lt;span class="p"&gt;  -&lt;/span&gt; contains: result.state in ["active"]

&lt;span class="gu"&gt;### 2. http.get&lt;/span&gt;
args: { "url": "https://storefront.acme.com/api/health" }
assert:
&lt;span class="p"&gt;  -&lt;/span&gt; status: ok
&lt;span class="p"&gt;  -&lt;/span&gt; range: result.latency_ms in 0..2000
&lt;span class="p"&gt;  -&lt;/span&gt; contains: result.body has "&lt;span class="se"&gt;\"&lt;/span&gt;db&lt;span class="se"&gt;\"&lt;/span&gt;:&lt;span class="se"&gt;\"&lt;/span&gt;up&lt;span class="se"&gt;\"&lt;/span&gt;"

&lt;span class="gu"&gt;## Open questions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Step 1 &lt;span class="sb"&gt;`result.created_at`&lt;/span&gt; is a timestamp — excluded from byte
  comparison. Confirm this is intentional.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Two design choices worth noticing
&lt;/h2&gt;

&lt;p&gt;1.&lt;strong&gt;The assertion grammar is small on purpose.&lt;/strong&gt; Five checks — status, type, regex, range, contains. They survive expected variation (a fresh timestamp doesn't fail a type check) but catch structural change: a renamed field, an auth error, HTML where JSON used to be.&lt;br&gt;
Assertions, not vibes. No embedding similarity, no "close enough" thresholds.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The compiler doesn't guess.&lt;/strong&gt; Values it can't prove stable — dates, UUIDs, cursors — land in an honest ## Open questions section for you to resolve, instead of being silently baked in and breaking replay #2.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Step 3 — Replay it
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;reelier run nightly-deploy-check.skill.md&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That prints the receipt you saw up top. The 0 tokens isn't an estimate — no model ran.&lt;/p&gt;

&lt;p&gt;One more thing in that receipt: if a step had recorded a write (a POST, a create_* tool), it would be skipped with a warning unless you passed --allow-writes. That default exists because re-firing a recorded write against a changed world is the one mistake this tool refuses to make for you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4 — reelier diff as a CI gate
&lt;/h2&gt;

&lt;p&gt;diff compares runs step by step, reports SAME or DRIFTED, and exits 1 on drift. That exit code is the whole trick for CI:&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;reelier run nightly-deploy-check.skill.md
reelier diff nightly-deploy-check
nightly-deploy-check: 2026-07-20 → 2026-07-21
  1. github.get_latest_deployment .. SAME
  2. http.get ...................... DRIFTED
     assert failed: contains result.body has "\"db\":\"up\""
     got: {"db":"degraded", ...}
exit 1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When something drifts, Reelier proposes — it never auto-heals. A silently self-patching test is not a test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wire it into GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Minimal workflow (there's also a published action in the repo if you prefer uses: over managing the install):&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent-drift-check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;6&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*"&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&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;actions/checkout@v4&lt;/span&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;actions/setup-node@v4&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;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm i -g reelier&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reelier run skills/nightly-deploy-check.skill.md&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reelier diff nightly-deploy-check&lt;/span&gt;
        &lt;span class="c1"&gt;# diff exits 1 on DRIFTED → the job fails → you get pinged&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now compare the economics with re-running the agent itself on that schedule. &lt;/p&gt;

&lt;p&gt;A 15-minute cron is &lt;strong&gt;2,880 model calls a month.&lt;/strong&gt; I've worked that math — with OpenClaw's documented heartbeat costs as the worst case, it lands at &lt;strong&gt;$1,728/month&lt;/strong&gt; at Opus prices — at reelier.com/blog/openclaw-cron-costs. Replay makes the recurring cost effectively zero, which is the entire point of reelier.com/blog/scheduled-agents-zero-token.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 — MCP-native: let your agent record itself
&lt;/h2&gt;

&lt;p&gt;Reelier is also an MCP server, so your agent can freeze and replay its own workflows mid-session. For Claude Code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;claude mcp add reelier -- npx -y reelier serve&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For Cursor / Windsurf / anything that takes an mcpServers JSON block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reelier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reelier"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This exposes reelier_scan, reelier_from_session, reelier_replay, and reelier_diff to the agent itself.&lt;/p&gt;

&lt;p&gt;The workflow I actually use: finish a task that was mostly tool calls, then tell the agent "freeze that as a skill." Next time it replays instead of re-reasoning — and hands me the receipt.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell you before you try it ⚠️
&lt;/h2&gt;

&lt;p&gt;Honest limits, so you don't find out the hard way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Judgment steps still need a model. Replay covers the deterministic core — fetch, check, transform, report. Triage and synthesis don't replay; there's an opt-in BYOK escalation for those steps.&lt;/li&gt;
&lt;li&gt;Writes are gated. Read-only by default; --allow-writes is per-skill and deliberate.&lt;/li&gt;
&lt;li&gt;Non-repeating workflows gain nothing. If every run is genuinely novel, there's nothing to snapshot.&lt;/li&gt;
&lt;li&gt;The first run costs normal tokens. You pay once to record; the win amortizes over every scheduled re-run.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Three takeaways, same as promised at the top:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Record a working agent run once → compile to SKILL.md with zero LLM calls&lt;/li&gt;
&lt;li&gt;Replay deterministically: 0 tokens, 48ms, 1,000/1,000 byte-identical in the published benchmark&lt;/li&gt;
&lt;li&gt;reelier diff exits 1 on drift → your CI already knows what to do with that&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Repo, benchmark data, and the run records behind the 0-token claim: &lt;a href="//github.com/seldonframe/reelier."&gt;github.com/seldonframe/reelier.&lt;/a&gt; The cost math lives at &lt;a href="//reelier.com/blog/openclaw-cron-costs"&gt;reelier.com/blog/openclaw-cron-costs&lt;/a&gt; and &lt;a href="//reelier.com/blog/scheduled-agents-zero-token"&gt;reelier.com/blog/scheduled-agents-zero-token&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; I'm the author of Reelier — it's AGPL, local-first, and free.&lt;/p&gt;

&lt;p&gt;Your turn: what's the agent workflow you re-pay for most often — a deploy check, a metrics pull, a report loop? Tell me in the comments and I'll tell you whether replay would actually cover it (including when the honest answer is "it wouldn't"). 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>mcp</category>
      <category>agents</category>
    </item>
    <item>
      <title>I built an open-source "CI for AI agents", and here is why I went open-source</title>
      <dc:creator>Maxime Houle</dc:creator>
      <pubDate>Mon, 20 Jul 2026 15:14:39 +0000</pubDate>
      <link>https://dev.to/maximehoule/i-built-an-open-source-ci-for-ai-agents-and-here-is-why-i-went-open-source-47nn</link>
      <guid>https://dev.to/maximehoule/i-built-an-open-source-ci-for-ai-agents-and-here-is-why-i-went-open-source-47nn</guid>
      <description>&lt;p&gt;Hi, my name is &lt;a href="https://x.com/themaxthule" rel="noopener noreferrer"&gt;Max&lt;/a&gt;. I built &lt;a href="https://github.com/seldonframe/reelier" rel="noopener noreferrer"&gt;Reelier&lt;/a&gt;, an open-source tool that gives AI agent workflows the thing normal code has had for decades: snapshot tests and CI.&lt;/p&gt;

&lt;p&gt;Here is the itch. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My coding agent kept re-deriving the same tool-call workflow on every run. &lt;/li&gt;
&lt;li&gt;Fetch this, transform that, post the result. &lt;/li&gt;
&lt;li&gt;Same tokens, same seconds, for a task with exactly one correct answer. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And every so often it did it a little differently, and nothing caught it. That second part is the scary one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbkh2u8b4ja95rqnygg2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbkh2u8b4ja95rqnygg2n.png" alt=" " width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why open-source it
&lt;/h2&gt;

&lt;p&gt;Agent tooling is flooded right now. New closed tools ship every day, and most of them ask you to trust a black box with your workflows and your keys. &lt;/p&gt;

&lt;p&gt;Open-source is how a small tool earns trust in that noise: you can read exactly what it does, run it on your own machine, and keep your data as plain files.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fczp0dmo36dp2x0dnp0ip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fczp0dmo36dp2x0dnp0ip.png" alt=" " width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You record one agent run that worked. &lt;/li&gt;
&lt;li&gt;Reelier compiles it into a readable SKILL.md file, a recipe with typed inputs, typed outputs, and an assertion on every step. &lt;/li&gt;
&lt;li&gt;Then it replays that file deterministically: no model call, 0 tokens, byte-identical, in milliseconds. &lt;/li&gt;
&lt;li&gt;Every replay is a receipt. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And reelier diff compares two runs and exits 1 when a step drifts, so a silent regression fails your build instead of reaching production.&lt;/p&gt;

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

&lt;p&gt;It only replays deterministic tool calls, HTTP and MCP. &lt;/p&gt;

&lt;p&gt;It does not replay file edits or free-form reasoning, and it never fabricates a step it cannot reproduce. It is for the deterministic half of what agents do. &lt;/p&gt;

&lt;p&gt;I say that up front because the version that would go viral (record my whole agent) is the version I will not claim, since it would not be true.&lt;/p&gt;

&lt;p&gt;Numbers, from the benchmark in the repo: 1000 of 1000 replays byte-identical, 0 tokens per replay, about 50x cheaper and 59x faster than the agent re-running the same task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbcg47avefcsxj3vc2l0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbcg47avefcsxj3vc2l0p.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is AGPL-3.0, BYOK, and runs entirely on your machine.&lt;/p&gt;

&lt;p&gt;Any help you can give me would be super tremendous! 🥹&lt;br&gt;
I would be happy to get a star if possible ❤️&lt;a href="https://github.com/seldonframe/reelier" rel="noopener noreferrer"&gt;https://github.com/seldonframe/reelier&lt;/a&gt;. &lt;/p&gt;

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