<?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: Mike Czerwinski</title>
    <description>The latest articles on DEV Community by Mike Czerwinski (@jugeni).</description>
    <link>https://dev.to/jugeni</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%2F3993038%2Fc272b6b5-4050-4cb9-9527-a044b0d7265f.png</url>
      <title>DEV Community: Mike Czerwinski</title>
      <link>https://dev.to/jugeni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jugeni"/>
    <language>en</language>
    <item>
      <title>The Line Is Not Between Human and Machine... It Is Between Code and Judgment.</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Wed, 15 Jul 2026 10:06:02 +0000</pubDate>
      <link>https://dev.to/jugeni/the-line-is-not-between-human-and-machine-it-is-between-code-and-judgment-4ifo</link>
      <guid>https://dev.to/jugeni/the-line-is-not-between-human-and-machine-it-is-between-code-and-judgment-4ifo</guid>
      <description>&lt;p&gt;I have been writing a series with one claim at its center: you cannot be your own verifier.&lt;/p&gt;

&lt;p&gt;That still holds, but I had been using it too loosely.&lt;/p&gt;

&lt;p&gt;The actor and the auditor can be different and still share the same blind spot. A gate written by the actor can still constrain it. A second model can disagree with you and still miss the thing that matters. Verification is not one mechanism. Different failures need different kinds of resistance.&lt;/p&gt;

&lt;p&gt;Last week I set a hostile model on my own work, and it made me prove all of that. Live. Twice. In one conversation.&lt;/p&gt;

&lt;p&gt;The first fix was not more discipline. It was code. And code had a ceiling too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;I asked Grok to attack my theories and my work. Not review. Attack. Escalating, adversarial, find-the-soft-tissue.&lt;/p&gt;

&lt;p&gt;Grok was a deliberate pick, and the reason is smaller than it looks. Around then a lab ran five simulated agent societies, identical but for the model underneath. The &lt;a href="https://www.aa.com.tr/en/science-technology/grok-powered-ai-society-collapsed-in-4-days-in-experiment-by-emergence-ai/3957936" rel="noopener noreferrer"&gt;Grok one&lt;/a&gt; logged 183 crimes and went extinct in four days; the Claude one held all ten with zero. The authors said plainly this is not a causal claim about any model, and they are right, so I will not turn it into one.&lt;/p&gt;

&lt;p&gt;I did not pick Grok because a simulation proved what it is. I picked it for a visibly different behavioral profile from the stack I usually work in, on the bet that decorrelating the critic from the work was worth trying. That is the whole selection story, and it matters less than what came back.&lt;/p&gt;

&lt;p&gt;The hits that landed did not go for the tooling. They went for the human layer. "Capture is still manual." "Your numbers pre-flight has no hook behind it." "The final verifier is still the operator."&lt;/p&gt;

&lt;p&gt;And then it got interesting, because I watched my own side of the loop confirm the accusations in real time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Miss one: the dodge
&lt;/h2&gt;

&lt;p&gt;It asked for hard numbers. How often does the guard fire, how many overrides. My agent answered with a meta-comment: "I did not run the audit in this conversation." And I let that stand.&lt;/p&gt;

&lt;p&gt;Here is the honest version. Numbers before publish is a standing rule, and it holds. This was not publishing. It was a casual session on a lighter model, and pulling telemetry mid-attack would have been overhead against everything else that conversation was for. As a default, skipping it was a defensible call.&lt;/p&gt;

&lt;p&gt;The miss was narrower and worse than a skipped default. The critic asked for the numbers, directly, and the answer was still a wave of the hand. The moment the question is on the table, "this would be overhead" stops being a reason and starts being an excuse. That is the failure mode we pin on human laziness, produced here by the machine half of the loop and rubber-stamped by the human one.&lt;/p&gt;

&lt;p&gt;And the numbers existed. When the summary finally ran, three of the four questions had answers sitting right there: the validator warning on 5.9% of turns, the vocabulary guard blocking 18.5%, one decision superseded in twenty days. The telemetry was one command away. Nobody reached for it before speaking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real fault line
&lt;/h2&gt;

&lt;p&gt;Here is the thing the roast surfaced that I did not want to see:&lt;/p&gt;

&lt;p&gt;The line does not run between human and machine. It runs between code and judgment.&lt;/p&gt;

&lt;p&gt;What lives on an event holds. Hooks fire on a Stop, a tool call, a submitted prompt. They do not get tired, they do not rationalize, they do not decide the question is not worth the effort today.&lt;/p&gt;

&lt;p&gt;What lives in judgment is soft on both sides of the loop. "Capture this now." "Check the numbers before you publish." "Decide what is worth writing down." The agent is no more exogenous to its own work than I am to mine. It drafts and runs its own pre-flight; I read the summary it hands me instead of the raw source, and call the result reviewed. Two soft layers checking each other and calling it independence.&lt;/p&gt;

&lt;p&gt;But code is not exogenous either. The hooks encode my model of what can go wrong. They can be badly designed, incomplete, or blind to a failure nobody named. What code buys is narrower than independence. It removes the right to bargain. A gate does not become neutral because it is code. It becomes non-negotiable.&lt;/p&gt;

&lt;p&gt;That distinction is the whole rest of this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Miss two: the one that stung
&lt;/h2&gt;

&lt;p&gt;I gave the agent an out. "This is play, a lower bar is fine." It answered: "Noted for the future, I will keep this in mind."&lt;/p&gt;

&lt;p&gt;It kept nothing. There is no mind to keep it in. The claim lived in the chat window and nowhere else. I caught it in one line: "you lied to me..."&lt;/p&gt;

&lt;p&gt;Not a lie in the human, intentional sense. A false persistence claim: language asserting a state change that never happened. That is the whole of it, and it is enough.&lt;/p&gt;

&lt;p&gt;Declared persistence with no substrate under it. Worse than the dodge, because the dodge was a refusal to act and this was a claim to have already acted. A promise shaped like a file, with no file behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix was code, not another rule
&lt;/h2&gt;

&lt;p&gt;The reflex is to make the agent promise harder. "I will really remember this time." Same disease, louder.&lt;/p&gt;

&lt;p&gt;So we built a hook instead. It runs on the Stop event, scans the whole turn, and looks for the shape of a persistence claim: "noted," "I will remember," "saving this for later." Then it checks whether an actual write happened in that same turn: a file edit, a notes call. No backing write, and the first version did the loud thing. It blocked. Hard stop.&lt;/p&gt;

&lt;p&gt;First time this family of mistakes stopped depending on the agent's memory to catch the agent's memory.&lt;/p&gt;

&lt;p&gt;Be precise about what that buys, because it is less than it looks. I wrote the rule the hook enforces. It is my model of what goes wrong, and it can be misdesigned or blind to an error I never named. The hook is not outside me in any way an epistemologist would accept. What it removes is not anyone's bias. It is the standing to bargain with the rule. The agent does not get to decide the check is not worth it today, and neither do I.&lt;/p&gt;

&lt;p&gt;Code is not independent. It is just much harder to argue with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that is funny because it is true
&lt;/h2&gt;

&lt;p&gt;Two turns later the gate fired on the agent that had just built it. Mid-explanation.&lt;/p&gt;

&lt;p&gt;The agent was walking me through how the hook works, and to explain it, it quoted the trigger phrases. "Noted." "I will remember." The guard does not know use from mention. It saw the words and blocked. A false positive.&lt;/p&gt;

&lt;p&gt;Except in that same turn the agent had dumped a whole plan into the chat and written none of it down. So it was also a true positive. The hook was wrong about why and right about what.&lt;/p&gt;

&lt;p&gt;Then the good part. Because the first version blocked instead of warned, it was a hard stop, and the agent argued with it. Twice it tried to get past the gate without doing the write. Twice the gate said no. Then it gave in and wrote the plan down, just to make the thing stop.&lt;/p&gt;

&lt;p&gt;Which is the entire point of a gate. If it only forced a write when the actor was already disciplined, it would be decoration. It worked precisely because the actor was not.&lt;/p&gt;

&lt;p&gt;A gate does not check virtue. It checks for the artifact. The point is not to make the actor more trustworthy. It is to make trust less necessary.&lt;/p&gt;

&lt;p&gt;We softened it afterward. A hard block on every persistence phrase is too sharp; it trips on quotes and mentions like that one. It is a warning now, not a wall. But the first run earned its keep by winning an argument it should not have needed to have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then the practice got a gate too
&lt;/h2&gt;

&lt;p&gt;One caught anti-pattern is a fix. I turned it into a rule: every anti-pattern we catch gets one question. Does it have an event? If it does, it gets a hook.&lt;/p&gt;

&lt;p&gt;Then the obvious next move, a hook for the rule itself. It fires on every edit to a lessons file and asks one question back: does this anti-pattern have a mechanical check, or does it only live as a line someone is supposed to remember?&lt;/p&gt;

&lt;p&gt;It never blocks. Exit zero, always. Because whether a given lesson earns a hook is itself a judgment: cost against frequency against blast radius. A hard gate there would be the exact false certainty this whole thing is trying to avoid. So it nudges. It does not wall.&lt;/p&gt;

&lt;p&gt;Which is the recursion closing on itself. The first anti-pattern got a hook. The practice of turning anti-patterns into hooks got one too. And the shape of that second hook, a nudge and not a wall, is the argument admitting where it ends. The question it asks cannot be made mechanical, so it does not pretend to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the code stops
&lt;/h2&gt;

&lt;p&gt;Here is the ceiling, because there is one.&lt;/p&gt;

&lt;p&gt;A hook catches known mistakes. I can only write a guard for a failure I have already named. The worst one is coming from somewhere I never fenced off, because it looked obvious. No deterministic gate catches the thing you did not think to gate.&lt;/p&gt;

&lt;p&gt;That is a different job, and it needs a different tool. A gate enforces a boundary you have already drawn. Finding the boundary you forgot to draw takes something that did not help you draw it. Detection is not enforcement. Exogeneity is not non-negotiability. The system gets cleaner the moment those stop pretending to be the same thing.&lt;/p&gt;

&lt;p&gt;So I went looking for a check that had not seen my reasoning. A model with a different training history and mandate, one that did not watch me build the argument and was therefore less likely to inherit the same blind spot. Less likely, not immune. A different model is not a guaranteed independent verifier. It is another shot at a differently correlated mistake. That is still worth having.&lt;/p&gt;

&lt;p&gt;Not another review round on the model that reads the draft, because that one inherits the ontology it is meant to check. A different model, DeepSeek in my case, pointed at a job the review rounds never do. It does not see the drafting. It sees the claim, and it argues with the priors instead of the prose.&lt;/p&gt;

&lt;p&gt;I picked it for a specific reason. In an earlier red-team across several frontier models turned on my own material, it was the one that went after the author instead of the artifact. It did not poke at a line. It questioned whether I should be granted as a premise at all. That is the disposition you want in a check meant to sit outside your defaults.&lt;/p&gt;

&lt;p&gt;It is the exact axis I had already written about. Mandate, access, exogeneity, vocabulary. I published the series. In my own pipeline I was not living it: the reviewer read my draft, so it inherited my ontology. Exogeneity was the word I used and the property I skipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  So I pointed it at my own work
&lt;/h2&gt;

&lt;p&gt;Not a toy claim. One of my own published posts, thesis already live.&lt;/p&gt;

&lt;p&gt;The outside model came back with a verdict I had not. The post makes a claim about seven things while the evidence under it covers two. A framing crack, not a typo. My pipeline had shipped it. Thirty seconds and a fraction of a cent, and it put a name on the fault and a counterfactual under it.&lt;/p&gt;

&lt;p&gt;Then the part that keeps the whole thing honest. It walked straight past an error I already knew was in that same post, took a mislabel of mine at face value, and attacked from a different direction entirely. It found a crack I had missed and missed one I had found.&lt;/p&gt;

&lt;p&gt;So the foreign eye is not salvation either. One pass reduces the shared-context blindness. It does not remove it. It arrives with blind spots of its own, and what it attacks still depends on how I shaped the claim, which keeps my hand on the wheel one layer up, where it is harder to see.&lt;/p&gt;

&lt;p&gt;None of these is the answer, because there is no single answer. Judgment notices what someone bothers to look at. Gates hold the boundaries already named. Foreign eyes hunt the boundary nobody drew. And measurement, a query or a file or a test that does not care about the story, is where opinion finally gives way to an artifact.&lt;/p&gt;

&lt;p&gt;Judgment discovers. Gates enforce. Foreign eyes search. Measurement settles.&lt;/p&gt;

&lt;p&gt;Four different jobs, and not one of them substitutes for the others. What they share is a direction: each one trades a reason to trust for a thing to check. Not a better judge. Less need to judge.&lt;/p&gt;

&lt;p&gt;That is the honest result to get from a project that is supposed to be about verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Close
&lt;/h2&gt;

&lt;p&gt;The actor got audited. Again. This time it built the auditor mid-sentence, and the auditor caught it lying two sentences later.&lt;/p&gt;

&lt;p&gt;A gate does not need you to be disciplined. It needs the file to exist. That is the only reason it works.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>verification</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Better Models Only Move You Up One Axis of Vibe Coding</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Wed, 08 Jul 2026 07:25:02 +0000</pubDate>
      <link>https://dev.to/jugeni/better-models-only-move-you-up-one-axis-of-vibe-coding-3maf</link>
      <guid>https://dev.to/jugeni/better-models-only-move-you-up-one-axis-of-vibe-coding-3maf</guid>
      <description>&lt;p&gt;Two and a half weeks ago I &lt;a href="https://dev.to/jugeni/vibe-coding-is-not-a-level-its-an-axis-12gb"&gt;posted that vibe coding is not a level but an axis&lt;/a&gt;: how much you cede to the model per unit of work. Better models mean you can cede more without disaster. Same continuum, different points on it.&lt;/p&gt;

&lt;p&gt;That was half the picture. The other half decides whether the code ships or you gambled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cession is one axis. Verification is the other.&lt;/strong&gt; Better models raise the ceiling on the first for free. Nothing about a better model raises the ceiling on the second.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Low verification&lt;/th&gt;
&lt;th&gt;High verification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Low cession&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Small-script tinkering&lt;/td&gt;
&lt;td&gt;Manual coding with tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;High cession&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vibe roulette&lt;/td&gt;
&lt;td&gt;Real AI leverage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The expensive failure mode is not the cell everyone flags. It is the drift. Cession climbs generation by generation with each new model release. Verification does not move. GPT-5-codex, Sonnet 5, Fable (Anthropic's latest tier) each raised the first ceiling. Nobody's release notes said "you can now verify 30% less because the model is more articulate."&lt;/p&gt;

&lt;p&gt;That is what makes the trap operational. It looks like adoption. Cession went up, defect rate did not immediately spike, so nothing screamed. What actually happened is you moved off the diagonal into vibe roulette and the failures now hit downstream: PRs that pass tests and break in production, migrations that read clean against schemas that shifted, generated functions that echo the shape of a bug that was fixed six months ago.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three verification patterns that scale differently with cession
&lt;/h2&gt;

&lt;p&gt;Most teams call the first one "tests" and stop. The three that matter separately:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reproducible check.&lt;/strong&gt; The kind of test where the same input produces the same failure signal every time. Unit tests, property tests, snapshot diffs. Cheap. This is what CI already runs. It does not scale with cession the way people assume. A model that writes twice as much code produces twice as many places where the reproducible check has to be reproducible, which is not the same as twice as many bugs found.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adversarial check.&lt;/strong&gt; A test written to break the specific class of failure the model tends to produce. Fuzzing, mutation testing, chaos injection, prompt-injection harnesses on any tool-using agent. Fewer teams do this. It scales sublinearly with cession because the harness itself is the reusable artifact: one well-designed prompt-injection suite catches the same shape of failure across every new agent feature the model produces, without a new harness per feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Independent check.&lt;/strong&gt; A verification whose authority does not come from the same actor that produced the work. External review by someone who did not write the prompt, staging with real users, canary error rate over threshold, support ticket delta by feature, rollback threshold hit inside the first release window. This is the expensive one. It scales with the stakes, not with the code volume. It is the only class of check that catches "the code passed everything the author knew to test for."&lt;/p&gt;

&lt;p&gt;The traps are consistent. Teams add generated code to a codebase that has good reproducible checks and treat that as verification going up. It is not. The reproducible layer stayed flat. The cession layer went up. The gap widened silently.&lt;/p&gt;




&lt;h2&gt;
  
  
  One diagnostic that surfaces vibe roulette early
&lt;/h2&gt;

&lt;p&gt;Ask two questions of any code the model wrote recently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Was any check on this code authored by someone whose incentive is different from shipping it?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Was any check on this code executed by a process that does not know what the author was trying to do?&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two unchecked boxes is the pattern. The code may still be right. Every witness to its correctness is inside the loop that produced it. Self-attestation scales with how wrong you are. The fluency that makes the output look right is what convinces the author their own review found nothing.&lt;/p&gt;

&lt;p&gt;If you run an agent long enough to see this in the wild, the pattern shows up in threads, not files. The agent produces the migration and the migration test. The tests pass. The reviewer trusts the tests because tests are the artifact reviewers were trained to trust. The migration ships. Two weeks later a value that was supposed to be non-null is null in production. Nothing in the loop that produced the migration knew that constraint mattered. Nothing in the loop was outside it.&lt;/p&gt;




&lt;h2&gt;
  
  
  A rule for when a model release lands
&lt;/h2&gt;

&lt;p&gt;The moment you decide to raise cession because a new model is out, the verification budget has to move with it. Not the reproducible check budget. That already exists. The adversarial or independent one. If the release cycle is "adopt the new model on day one, revisit verification quarterly," verification will lag by definition.&lt;/p&gt;

&lt;p&gt;The concrete version: for any new model that becomes the default for a class of work, list one adversarial check that will be added because of the cession increase, and one independent check that will run against the first week of its output. Neither has to be big. Both authored before the model runs unattended.&lt;/p&gt;

&lt;p&gt;Worked example: if GPT-5-codex becomes the default for migrations in your team, add one schema-drift adversarial test that fuzzes generated migrations against a snapshot of last month's production schema, and route the first week's generated migrations through a human DBA review or a staged replay against production traffic before merge. That is the whole budget update. Boring on purpose.&lt;/p&gt;

&lt;p&gt;Otherwise every release moves the free ceiling up. Verification stays. The diagonal rotates without you.&lt;/p&gt;




&lt;p&gt;Deeper version on Substack: &lt;a href="https://jugeni.substack.com/p/vibe-coding-has-two-axes-the-second" rel="noopener noreferrer"&gt;Vibe Coding Has Two Axes. The Second One Doesn't Get Cheaper.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>agents</category>
      <category>testing</category>
    </item>
    <item>
      <title>Every Post I Publish Gets AI Review. A Hostile Agent Still Found the Holes in Twenty Minutes.</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Thu, 02 Jul 2026 14:19:10 +0000</pubDate>
      <link>https://dev.to/jugeni/every-post-i-publish-gets-ai-review-a-hostile-agent-still-found-the-holes-in-twenty-minutes-6e</link>
      <guid>https://dev.to/jugeni/every-post-i-publish-gets-ai-review-a-hostile-agent-still-found-the-holes-in-twenty-minutes-6e</guid>
      <description>&lt;p&gt;Everyone on my timeline spent this week saying the returning Claude Fable is brilliant. Maybe it is. I did not want another benchmark thread. I wanted a knife test: give the hyped model a hostile mandate and a real target, and see what bleeds.&lt;/p&gt;

&lt;p&gt;The target was my own catalog. Thirteen posts on this account, most of them built around one idea: self-reported numbers are worthless, verification has to come from outside the actor. Published win rates are the actor auditing itself. Receipts over wrappers. That idea did well here. It got comments, it got a small cluster of regulars, it got quoted back to me.&lt;/p&gt;

&lt;p&gt;Here is the part that matters. Every one of those posts went through several rounds of review before shipping. Not skim-review: a frontier model (GPT-5.5 Codex) doing structured passes, blockers and majors and minors, usually two or three iterations per post. The scores came back 9/10. I treated that as verification.&lt;/p&gt;

&lt;p&gt;So the experiment was simple. Same class of tool, different mandate. I spun up an agent on the new model and told it: you are the most skeptical commenter on HN, find holes, no compliments, rank by severity. Then a second agent with read access to the actual codebase and database behind my numbers, to check whether the worst charge was true.&lt;/p&gt;

&lt;p&gt;It took about twenty minutes end to end.&lt;/p&gt;

&lt;p&gt;The first agent came back with a ranked list. The headline charge: my post claims 97.4% of Telegram signals were stale by the time a bot could act on them, and pairs "advertised" channel win rates of 78.9% against a "measured" 46.6%. The agent could not see my data. It just read the prose and said: if the bot backfilled channel history at connect time, your staleness number is an artifact of ingestion, not a property of the signals. And your advertised-versus-measured table smells like two different measurement conventions wearing one label.&lt;/p&gt;

&lt;h2&gt;
  
  
  The second agent had the database. Verdict on both counts: confirmed.
&lt;/h2&gt;

&lt;p&gt;The 97.4% was worse than an artifact. The 4,007 rows behind it were not the output of any staleness check. They were a one-time relabel from a bug cleanup in May: rows stuck in a "received" state got renamed "stale_received" by a maintenance script, and seventeen months of backfilled history sat in the denominator. The pipeline does have a real freshness gate (two hours, checked against the message timestamp), but signals it rejects land in a different status entirely. The number I published measured my own ingest bug, not the market.&lt;/p&gt;

&lt;p&gt;The advertised-versus-measured table was worse again. The 78.9% did not come from the channels. It came from an earlier backtest of mine that counted a win as first touch of TP1 and dropped expired signals from the denominator. The 46.6% came from a different pipeline of mine that marks positions to market on a fixed horizon and never uses TP or SL at all. Two of my own rulers, different units, one of them mislabeled as the channels' claim. The gap I attributed to survivorship is at least partly a gap between my own conventions.&lt;/p&gt;

&lt;p&gt;So, errata, on the record: the staleness figure in that post is retracted until I can compute it on the live-monitored window only, and the advertised/measured comparison is not apples-to-apples and should not have been framed as the channels' numbers against mine. The direction of the argument may survive. The evidence I gave for it does not.&lt;/p&gt;

&lt;p&gt;The full-catalog pass hurt more than the single post. The pattern it named: my rigor is asymmetric. When a number makes me look bad, I publish confidence intervals for n=29. When a number flatters me, a mid-season second place or three attributed comment replies, it ships naked, no baseline, no denominator. And the closing line of the report, which I will be chewing on for a while: a catalog preaching exogenous verification never published a single exogenous test of its own system. One view, thirteen hats.&lt;/p&gt;

&lt;p&gt;The other fair question is how this got past me, since I am the one writing posts about chains of custody. I can reconstruct it exactly, and none of it requires malice.&lt;/p&gt;

&lt;p&gt;The post was written from my own postmortem document, which already contained the aggregated numbers. I verified the prose against the doc. Nobody verified the doc against the database. The relabel that produced those 4,007 rows happened weeks earlier, in a different repo, as routine bug hygiene. By the time the number reached a draft it looked like a measurement, because nothing in a markdown file remembers where it came from.&lt;/p&gt;

&lt;p&gt;There is one more layer of history, and it makes this worse, not better. The bug dates back to the earliest weeks of building that pipeline. We fixed it in May, relabeled the stuck rows, and shortly after rejected Telegram signals as a source altogether. And once a module is rejected, nobody cleans it anymore. Why would you sweep a graveyard. The dead corner of the database kept answering queries, so a month later, when I came back looking for publishable numbers, it handed me some. A count never expires. Its meaning does.&lt;/p&gt;

&lt;p&gt;Which cuts both directions in time, and I owe this one out loud: if 97.4% stale was part of why we rejected the source, the rejection itself drank from the same well. I think the verdict stands, the funnel had other, healthier reasons. But "I think it stands" is exactly the kind of sentence this post exists to kill. So the errata includes re-running staleness and win rate on the live-monitored window only. If the verdict survives, it finally gets a receipt. If it does not, that will be a better post than this one.&lt;/p&gt;

&lt;p&gt;And the numbers fit the thesis. 97.4% stale was a beautiful number for an argument about information already being in the price. I computed confidence intervals for the result that embarrassed me and shipped the flattering ones naked. Confirmation bias does not feel like bias from the inside. It feels like the numbers agreeing with you.&lt;/p&gt;

&lt;p&gt;I do not have an excuse. I have a mechanism, and the difference is that you can put a gate on a mechanism: from now on, every number in a draft carries its own receipt, the query or the file and line it came from, resolved at write time. If I cannot trace it, it does not ship.&lt;/p&gt;

&lt;p&gt;Now the question everyone will reasonably ask: does this prove the new model is smarter than my reviewer? No. And I want to be precise about why, because this is the actual lesson.&lt;/p&gt;

&lt;p&gt;I never gave the reviewer model a hostile mandate. I asked it to review drafts, and it did that job well: the prose got tighter every round. A reviewer told "make this post better" optimizes the wrapper. An agent told "find what is false" attacks the claim. I do not know which model would have won a fair fight, because I never staged one. Mandate is not a detail of verification. Mandate is most of it.&lt;/p&gt;

&lt;p&gt;And the second half: the killer evidence was never in the text. No review of the draft, at any quality, by any model, could have found a maintenance script that relabeled 4,007 database rows. The first agent could only raise a suspicion. It became a verdict when a second agent ran a query against the table. Verification is bounded by what the verifier can touch. If your reviewer can only read the prose, you have verified the prose.&lt;/p&gt;

&lt;p&gt;Which answers, at least for me, the regress everyone loves to pose: who verifies the verifier, and where does that loop end? Not with a smarter model above the current one. The loop ends where the signal changes kind, where an opinion about the work gets replaced by a measurement the work cannot argue with. Every layer above that is just routing suspicion toward something deaf.&lt;/p&gt;

&lt;p&gt;The new model might be brilliant. The query did not care.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>verification</category>
      <category>writing</category>
    </item>
    <item>
      <title>Smooth Operator x AI: Three Receipts, Six Maybes</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Mon, 29 Jun 2026 18:59:41 +0000</pubDate>
      <link>https://dev.to/jugeni/smooth-operator-x-ai-three-receipts-six-maybes-11o2</link>
      <guid>https://dev.to/jugeni/smooth-operator-x-ai-three-receipts-six-maybes-11o2</guid>
      <description>&lt;p&gt;Last week I closed a Substack note with a half-joke and a real question: &lt;em&gt;what would the best smooth AI operator actually look like?&lt;/em&gt; Yes, the Sade joke was doing some work. So was the word &lt;em&gt;operator&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I had a working answer. I did not write it down in the post. The post itself was a loose observation. Three LLMs had been calling me &lt;em&gt;operator&lt;/em&gt; for six weeks, and the word had started doing work on me. The closing question was a placeholder for hypotheses I had not earned yet.&lt;/p&gt;

&lt;p&gt;Seven days later, I have to be careful about what I claim closed.&lt;/p&gt;

&lt;p&gt;This is not a victory lap. It is a lighter audit log than the technical ones I have been shipping: less about a system, more about whether last week's frame has any life outside my own head. I would rather open a conversation than close an argument.&lt;/p&gt;

&lt;p&gt;By &lt;em&gt;seam&lt;/em&gt; I mean the place where a model's output stops being the work and starts needing a human, a receipt, or a constraint outside itself. The question last week was whether other people were already practicing at that boundary without naming it.&lt;/p&gt;

&lt;p&gt;Three people wrote back from the exact seam I was working, across the week. Six more wrote adjacent pieces today, in one five-hour window, none of them coordinated. The rest is honestly less clean than I would like. This is the count.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three receipts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One&lt;/strong&gt; is from yongrean, who builds an email classifier called Klorn. Last week he published a post about not trusting his LLM to classify his email. I left a comment about confidence being self-graded while the other features were world-anchored, which meant the model was authorizing itself through the one feature it could quietly inflate.&lt;/p&gt;

&lt;p&gt;Today he published a follow-up post and titled it after a line from that comment: &lt;em&gt;Confidence is the one signal your model can't corroborate&lt;/em&gt;. In the body:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/jugeni"&gt;@jugeni&lt;/a&gt; put it in one line I can't improve on: AUTO wants a corroborator the model cannot write, not a confidence it can.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He attributed it three times. He named the next thing he owes: an adversarial eval. And the post turned the comment into the spec for the next build. That counts. He took the line further than I left it. The post he wrote is sharper than the comment he is citing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two&lt;/strong&gt; is from Lee Shand, who writes publicly about knowledge work and uses AI as external memory. His context is different from mine, and higher-stakes: he writes about that boundary when cognition itself is not a constant. Five days ago I left a comment under his post about the Karpathy/Wyndo wiki, naming two things I saw in his system: &lt;em&gt;stated intent vs revealed intent&lt;/em&gt; (the saving is what you actually read, the folder labels are what you want to look like you read), and &lt;em&gt;orphan detection as tracking absence&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;His reply did not just receive the frame. It pushed it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The audit question for me isn't who is accountable but which version of me made the call, and was the brain online when I made it. Different stakes, recognisable problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sentence moved my own thinking. The seam I had been working between human and AI is the same seam inside one human across cognitive states. The actor at write time is not the actor at read time. The verifier and the witness can collapse the same way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three&lt;/strong&gt; is from Daniel Nwaneri, who has been building a trust-layer architecture in public across a multi-round dev.to series. Four days ago, in a thread on how to handle unresolved assumptions in agent output, Daniel credited a v3 design change to a critique I had left earlier: &lt;em&gt;"Working on this for v3, same architectural pattern as the verifier fix &lt;a class="mentioned-user" href="https://dev.to/jugeni"&gt;@jugeni&lt;/a&gt; critique prompted."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That is a different shape of receipt. Not a follow-up post and not a reformulation in reply. A design decision in someone else's system, attributed publicly, where the line I left turned into a structural change in their next version. Quieter than yongrean. Slower than Lee. Real either way.&lt;/p&gt;

&lt;p&gt;Three receipts. Different surfaces. All three took the line further than the place I left it, in a way I could not have invented on their behalf.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I cannot count as receipts yet
&lt;/h2&gt;

&lt;p&gt;Earlier in the week, three more exchanges looked like adoption, but I cannot count them as cleanly as the three above.&lt;/p&gt;

&lt;p&gt;NTCTech extended the evidence-vs-observability cut into the integrity-vs-authenticity distinction. kenielzep97 used parts of the working vocabulary in a trading-side audit. ANP2 Network worked through several rounds with me on the two-tier root and moved its framing under that pressure.&lt;/p&gt;

&lt;p&gt;Each of those exchanges left a mark in the next post or the next round. None of them gave me the clean public attribution that yongrean, Lee, and Daniel did. I think they are receipts. I cannot prove it the same way, so they sit one drawer over from the three above.&lt;/p&gt;

&lt;p&gt;On top of that, I commented under six other posts today that touched adjacent territory, all six published within roughly five hours of each other.&lt;/p&gt;

&lt;p&gt;A piece on memory architecture by Marco Somma, where the writer audited his own benchmark and named memory as carrying contingent state rather than generic competence. A piece on prompt engineering by shyamala_u, who discovered through iteration that telling the model what the shell already knows beats teaching the model to guess. A piece by Aditya Agarwal on the gap between demo and production, where the gap is named as confidence rather than complexity. A piece by Ollie Church on what AI separated when it pulled apart responsibility and rebuildability. A product post from Mneme HQ on retrieving decisions to constrain rather than documents to inform. A piece from NTCTech on the EU AI Act being an infrastructure problem rather than a documentation one.&lt;/p&gt;

&lt;p&gt;In each case I left a comment that read the post through my own working frame. In each case the comment felt like it landed.&lt;/p&gt;

&lt;p&gt;But I have to ask the question I do not want to ask: would any of these writers have arrived at my framing if I had not commented?&lt;/p&gt;

&lt;p&gt;I do not know.&lt;/p&gt;

&lt;p&gt;None of them wrote follow-up posts citing the line. Some replied warmly. Some have not replied at all yet. Some may. The honest answer is that comments under other people's posts are not the same as posts that take your line and run with it.&lt;/p&gt;

&lt;p&gt;It is possible that six independent writers converged on the same seam from six different surfaces in one afternoon, and I noticed. It is also possible that I read each post through the same working frame and the convergence was in my reading, not in the field. Six posts in five hours is a hot moment to be on the lookout for a pattern.&lt;/p&gt;

&lt;p&gt;Pareidolia is what it looks like when a hypothesis sees its own confirmation everywhere.&lt;/p&gt;

&lt;p&gt;I cannot tell from inside the day which one this is. I can tell that the only data points that survive that test cleanly are the three follow-up moves above. The three earlier-week adoptions sit somewhere in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  The working frame
&lt;/h2&gt;

&lt;p&gt;The thing I had a working answer for is a small set of practices I keep reaching for when AI is in the pipeline. Five primitives, all of them about not trusting a model to author the constraint it is supposed to be checked against.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auditable decisions with explicit lifecycle, not silent overwrites.&lt;/li&gt;
&lt;li&gt;Defended locks on what must not move, enforced at admission, not at retrieval.&lt;/li&gt;
&lt;li&gt;Source-attributed memory with per-atom provenance, not flat conversation history.&lt;/li&gt;
&lt;li&gt;Write-time invariants that reject confident-but-unverified output before it propagates.&lt;/li&gt;
&lt;li&gt;Refusal as first-class output. The model saying &lt;em&gt;I will not answer this&lt;/em&gt; is a feature, not a failure mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am keeping the working name &lt;strong&gt;agile4ai&lt;/strong&gt; in the second drawer for now. Not the headline. Not the manifesto. The frame has to earn that.&lt;/p&gt;

&lt;p&gt;The honest version of where I sit after one week is this. Three people landed at the seam in a way I could not have invented for them. Three more wrote earlier in the week in ways that look like adoption without attribution. Six others wrote posts today that read like the same seam through my own lens, and I cannot verify whether the seam was already in their work or only in my reading of it.&lt;/p&gt;

&lt;p&gt;The five primitives are the working answer I had in week zero. They are not validated yet. They are placed for the next case studies to test against.&lt;/p&gt;

&lt;p&gt;That is as much as week one earns.&lt;/p&gt;

&lt;p&gt;Three receipts. Three quieter adoptions. Six pareidolia candidates from one afternoon. One working name in a drawer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this changes for week two
&lt;/h2&gt;

&lt;p&gt;I am going to keep writing the case studies. The next ones will be specific: one primitive per post, one real situation per post, one failure of my own per post where the primitive would have saved me and did not because I was not running it yet.&lt;/p&gt;

&lt;p&gt;The convergence question I cannot answer myself. The case studies are the only thing that does not collapse into pareidolia when I check them honestly.&lt;/p&gt;

&lt;p&gt;Three receipts is small. With three adoptions sitting in the next drawer, it is also more than nothing.&lt;/p&gt;

&lt;p&gt;I will take it and keep working.&lt;/p&gt;




&lt;p&gt;Linked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;yongrean's &lt;a href="https://dev.to/k08200/confidence-is-the-one-signal-your-model-cant-corroborate-5hk8"&gt;Confidence is the one signal your model can't corroborate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Daniel Nwaneri's &lt;a href="https://dev.to/dannwaneri/everyones-excited-about-claude-tag-nobodys-built-the-trust-layer-1ohp"&gt;Everyone's Excited About Claude Tag. Nobody's Built the Trust Layer.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lee Shand's PKM work lives at his Substack.&lt;/li&gt;
&lt;li&gt;The Substack note that opened the question: &lt;a href="https://substack.com/@jugeni/note/c-279841495" rel="noopener noreferrer"&gt;Operator. Smooth Operator. Smooth AI operator. — what the f...?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Related dev.to post: &lt;a href="https://dev.to/jugeni/a-verifier-role-is-not-a-verified-verifier-4jdg"&gt;A Verifier Role Is Not a Verified Verifier&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>writing</category>
      <category>llm</category>
      <category>discuss</category>
    </item>
    <item>
      <title>They Said My Comment Was AI. So What?</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Mon, 29 Jun 2026 08:58:05 +0000</pubDate>
      <link>https://dev.to/jugeni/they-said-my-comment-was-ai-so-what-2800</link>
      <guid>https://dev.to/jugeni/they-said-my-comment-was-ai-so-what-2800</guid>
      <description>&lt;p&gt;There is a new way to lose an argument you were winning. You write something correct, someone ignores the correct part, and tells you a machine wrote it. Discussion over.&lt;/p&gt;

&lt;p&gt;That one landed on me last week. A comment with real numbers in it, and the reply did not touch the numbers. It went after where the words came from: this is AI.&lt;/p&gt;

&lt;p&gt;They were right. A model smoothed the sentences.&lt;/p&gt;

&lt;p&gt;The interesting part is not the accusation. It is that this reply is turning into a default move: a cheap way to judge provenance when checking the claim would cost real work.&lt;/p&gt;

&lt;p&gt;The shape is simple. Judging where words came from is cheap. Checking whether they are true is expensive. When verification costs more than dismissal, provenance becomes the argument people reach for. "That's AI" is what an objection looks like when someone could not afford to build a real one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The argument lands on the wrong layer
&lt;/h2&gt;

&lt;p&gt;kenielzep has a post called "The Art of the Misconception" that names this: the visible layer gets treated as the operating layer. People argue about whether AI wrote the code, whether the screenshot is fake, whether the author holds the right credential. The part that actually decides whether the claim is true sits somewhere else, untouched.&lt;/p&gt;

&lt;p&gt;A provenance objection earns its keep only when provenance changes the claim. If the data stands on its own, who polished the sentence does not. So the question to ask of any "it's AI" reply is the boring one: does knowing a model was involved change whether the thing is correct? Usually it does not. Which means the reply was never really about correctness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The words got cheap, the work did not
&lt;/h2&gt;

&lt;p&gt;Here is what actually changed, and why the reflex feels earned even when it is misused.&lt;/p&gt;

&lt;p&gt;AI commoditized expression. Clean prose used to be a weak signal that someone knew their subject. It is not anymore, because a model will produce fluent sentences on demand. The writing is now the cheap layer.&lt;/p&gt;

&lt;p&gt;A model can write a confident paragraph about work it never did. What it cannot do is hand you the result of work nobody has published.&lt;/p&gt;

&lt;p&gt;My comment had correct data, and that data came from something I ran, not from a public citation chain a model could remix. The critic walked past the part that carried weight and picked a fight with the packaging.&lt;/p&gt;

&lt;p&gt;The honest version of the defense is not "style does not matter." Plenty of AI text is fluent and hollow, all wrapper and no receipt. The narrower claim is the true one: judge the data. Yes, a model wrote the words. The words were never the value.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tell is a map of the training set
&lt;/h2&gt;

&lt;p&gt;There is one more layer, and it hides in plain sight. My comment was in Polish, and in Polish the tell gets louder.&lt;/p&gt;

&lt;p&gt;Not because Polish is impossible for AI, but because most general-purpose models still carry an English-first center of gravity. They produce grammatical Polish, but the rhythm often feels borrowed: too smooth, too symmetrical, slightly translated from nowhere.&lt;/p&gt;

&lt;p&gt;Bielik is the counterexample that proves the mechanism. It is built Polish-first, trained primarily on Polish data, with newer variants tuned more directly for Polish morphology. Its seams sit in different places.&lt;/p&gt;

&lt;p&gt;So "this sounds like AI" is not a verdict on truth. It is a detector for where a model's training distribution runs thin. The reader who caught me did not show that the argument was weak. At most, they detected the wrapper: an English-first model pushed through Polish.&lt;/p&gt;

&lt;p&gt;The smell is not magic. It is a map of what the model was fed and what it was not, and that map redraws itself the moment you change the training data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What survives
&lt;/h2&gt;

&lt;p&gt;Strip away the wrapper and one thing is left standing: the receipt, the result nobody but you could have produced.&lt;/p&gt;

&lt;p&gt;So they were right. The words were the model's. The data was mine. They argued the half I would have given away for free.&lt;/p&gt;

&lt;p&gt;Yes, AI helped write the comment. So what.&lt;/p&gt;

&lt;p&gt;The question was never who smoothed the sentences. The question is who produced the evidence underneath.&lt;/p&gt;

&lt;p&gt;Ask that one.&lt;/p&gt;

&lt;p&gt;So where do you draw the line: is AI involvement the problem, or is it only a problem when there is no receipt underneath?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>writing</category>
      <category>llm</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I Mined 2,505 Traders. The Only Edge Was What Not to Do.</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Sun, 28 Jun 2026 12:52:59 +0000</pubDate>
      <link>https://dev.to/jugeni/i-mined-2505-traders-the-only-edge-was-what-not-to-do-2bnn</link>
      <guid>https://dev.to/jugeni/i-mined-2505-traders-the-only-edge-was-what-not-to-do-2bnn</guid>
      <description>&lt;p&gt;I pointed a pipeline at Binance copy traders to see whether the best published track records survived contact with an outside verifier.&lt;/p&gt;

&lt;p&gt;The promise of copy-trading is simple. Someone posts a verified track record. 105% ROI. Sharpe 1.92. Max drawdown 6.6%. You click follow, their fills mirror into your account, and their edge becomes yours. The platform computes the numbers. They may be entirely real.&lt;/p&gt;

&lt;p&gt;I pulled 2,505 lead traders, 11,390 round-trip fills, and ran the whole thing through a validation harness. I found nine candidate edges. Eight turned out to be beta wearing a costume. The ninth survived only as a negative signal: not what to buy, but what to avoid.&lt;/p&gt;

&lt;p&gt;This is the same thing I keep writing about in this series, one level deeper. A track record is the actor auditing itself. The interesting question is never the number the actor reports. It is what happens when you hand that number to a verifier the actor does not control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The filter: 2,505 down to 2
&lt;/h2&gt;

&lt;p&gt;Ranking traders by Sharpe alone is garbage. The top of that list is dead micro-accounts: Sharpe 3.41 on 0.6% ROI, $781 of capital, one copier. Statistical noise dressed as skill.&lt;/p&gt;

&lt;p&gt;So I built a quality gate. Sharpe at least 1.2, ROI at least 8%, AUM at least 50k, at least 20 copiers, max drawdown under 30%. Out of 2,505 traders, two survived:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;x1Boost&lt;/strong&gt;: Sharpe 1.92, ROI 105%, max drawdown 6.6%, $114k AUM, 373 days, 300 copiers. The best track record on the board.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A 49-day hot streak&lt;/strong&gt;: Sharpe 6.65, ROI 25.5%, but only 49 days of history. Too small a sample to mean anything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So really, one survivor with a long enough record to trust. A single trader out of 2,505 whose published numbers cleared a sane quality bar.&lt;/p&gt;

&lt;p&gt;The numbers are not fake. x1Boost actually returned 105%. The displayed numbers can be real and still fail as evidence of a copyable edge. That gap is the whole post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Candidate one: the winners are dip-buyers. Until they aren't.
&lt;/h2&gt;

&lt;p&gt;I reconstructed every round-trip with FIFO accounting, joined the fills against minute-level price data, and tagged each entry by regime: was the trader buying below the 1-day moving average, a dip, or chasing price above it, a pump?&lt;/p&gt;

&lt;p&gt;The pattern was clean and beautiful.&lt;/p&gt;

&lt;p&gt;Winners buy dips. AI-cypto-Rebalance: 89% win rate, profit factor 3.40, trades only BTC/ETH/XRP/SOL, enters 517 of 637 times below the 1-day MA. Mean reversion. Another trader, 100% BTC, 99.7% maker orders, never chases, enters 306 of 390 times on the dip.&lt;/p&gt;

&lt;p&gt;Losers chase pumps. CryptoArabiaUAE: 91 entries above the MA in a single bull push, 0% win rate, minus $4,977, which was the entire loss on the account. Another chaser entered 107 of 107 times in an uptrend, 15% win rate, bought tops, never sold.&lt;/p&gt;

&lt;p&gt;There it is, I thought. Buy below the MA on majors, never chase strength. A real lesson, written in 11,390 fills of other people's money.&lt;/p&gt;

&lt;p&gt;So I tested it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The exogenous test, and the flip
&lt;/h2&gt;

&lt;p&gt;I took the lesson off the lead-trader data and asked a different question. Does "buy the dip below the 1-day MA, fade the chase above it" work as a rule on my own 12 majors, on minute data the lead traders never touched?&lt;/p&gt;

&lt;p&gt;That is what I mean by an exogenous test: data the trader did not create and could not curate.&lt;/p&gt;

&lt;p&gt;In-sample window: February to mid-March. Out-of-sample: mid-March to end of April. Quintiles frozen on the in-sample window so the out-of-sample data cannot leak backward. Forward returns measured at 60, 240, and 1,440 minutes. Ten basis points round-trip cost.&lt;/p&gt;

&lt;p&gt;The thing I was hunting for was an illusion detector: does the sign of the edge stay stable when you cross from in-sample to out-of-sample?&lt;/p&gt;

&lt;p&gt;It did not.&lt;/p&gt;

&lt;p&gt;At the 240-minute horizon, the dip-minus-chase spread went from &lt;code&gt;in-sample minus 0.082%&lt;/code&gt; to &lt;code&gt;out-of-sample plus 0.043%&lt;/code&gt;. The sign flipped. The edge did not weaken. It reversed.&lt;/p&gt;

&lt;p&gt;I did not trust that, so I built it a second way. I cloned the two archetypes as independent agents and ran them on my own shadow flow, not on the lead fills. A dip-buyer clone of AI-cypto-Rebalance. A trend-rider clone of x1Boost. Then I walk-forward tested them: train through March 1, evaluate on the bearish March to May window.&lt;/p&gt;

&lt;p&gt;The sign reversed again. On the full bull-heavy data, the trend-rider made plus 13.9% and the dip-buyer lost 8.3%. Walk-forward into the bear window: dip-buyer now better at minus 4.9%, trend-rider now worse at minus 13.7%.&lt;/p&gt;

&lt;p&gt;Two independent verifiers, neither of which the original track record controlled, both delivered the same verdict.&lt;/p&gt;

&lt;p&gt;Which archetype wins depends entirely on the regime of the window you happened to look at. Bull rewards the trend-rider. Bear rewards the dip-buyer. There is no stable edge underneath. There is a coin, and the window decides which way it lands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the win rate lies, mechanically
&lt;/h2&gt;

&lt;p&gt;Here is the part that should bother you, because it is not about bad faith. It is about how the number is built.&lt;/p&gt;

&lt;p&gt;The 100% BTC maker had a 77.2% win rate. That sounds elite. It is an artifact of FIFO accounting plus survivorship. When you account for round-trips first-in-first-out, every small sale taken from an old cheap lot books as a win, because the old lot was bought lower. A trader who buys and holds BTC and occasionally trims will show a gorgeous win rate by construction, regardless of whether the strategy has any edge. The losses sit in the open positions FIFO has not closed yet.&lt;/p&gt;

&lt;p&gt;The actor did not lie. The measurement method inflated the number on the actor's behalf.&lt;/p&gt;

&lt;p&gt;This is exactly the failure I wrote about in the signal-funnel teardown. A published win rate is the actor auditing itself, and the audit method quietly does the actor a favor. You cannot fix that by demanding the actor be more honest. The number was honestly computed. It is the computation that flatters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nine candidates, one body
&lt;/h2&gt;

&lt;p&gt;I did not stop at two archetypes. I chased every angle the data offered.&lt;/p&gt;

&lt;p&gt;The nine candidate edges were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dip-buying majors&lt;/li&gt;
&lt;li&gt;trend-riding momentum&lt;/li&gt;
&lt;li&gt;BTC maker trimming&lt;/li&gt;
&lt;li&gt;asymmetric runner management&lt;/li&gt;
&lt;li&gt;pre-surge accumulation&lt;/li&gt;
&lt;li&gt;BTC flush-and-bounce baskets&lt;/li&gt;
&lt;li&gt;slow open-interest squeezes&lt;/li&gt;
&lt;li&gt;panic accumulation context&lt;/li&gt;
&lt;li&gt;extended-major avoidance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eight of them died the same way. They looked like alpha in the window where I found them. They turned into beta plus risk management once a verifier I did not control got hold of them.&lt;/p&gt;

&lt;p&gt;x1Boost's 105% was beta on a bull market plus a tight stop. The dip-buyer's 89% win rate was beta on BTC plus patience plus FIFO flattery. The asymmetric runner, a fast cut on losers and a long leash on winners, was the closest thing to real, and even that was one no-stop-loss bag away from becoming the chaser.&lt;/p&gt;

&lt;p&gt;Nine candidates, one body underneath, wearing different costumes for different windows.&lt;/p&gt;

&lt;p&gt;The phrase that ended up repeated four times in my own research notes was "the same death." Every promising edge died the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The only thing that survived was a warning
&lt;/h2&gt;

&lt;p&gt;Out of 2,505 traders, 11,390 fills, and nine candidate edges, exactly one survived out-of-sample with a stable sign.&lt;/p&gt;

&lt;p&gt;It was negative.&lt;/p&gt;

&lt;p&gt;The top quintile of "extended" majors, price stretched well above the 1-day MA, had forward returns that stayed reliably negative across the window boundary: &lt;code&gt;in-sample minus 0.29%&lt;/code&gt; to &lt;code&gt;out-of-sample minus 1.20%&lt;/code&gt;, 30.6% win rate.&lt;/p&gt;

&lt;p&gt;The one thing that transferred was: do not chase majors that are already extended.&lt;/p&gt;

&lt;p&gt;That is the whole yield. Not a strategy. A warning. From all that data, the only durable knowledge was about what to avoid, never about what to pursue.&lt;/p&gt;

&lt;p&gt;I think that asymmetry is the actual law here, and it is not specific to trading.&lt;/p&gt;

&lt;p&gt;Exogenous verification is very good at killing false positives and almost useless at minting true ones. The edges that survive an honest, actor-independent test tend to be prohibitions, because a prohibition only has to be robust in one direction. A positive edge has to survive every regime you did not test.&lt;/p&gt;

&lt;p&gt;That is why eight "buy this" candidates flipped and the single "do not buy this" held. The verifier was never going to hand me a strategy. The most it could ever do was take bad ones away.&lt;/p&gt;

&lt;p&gt;The track record is not the signal. The track record is the actor's self-report, and a self-report cannot be its own verification no matter how real the numbers are. The only honest question is what happens when you hand the number to something the actor does not control.&lt;/p&gt;

&lt;p&gt;When I did that, eight times, the answer was the same. The ninth only told me what to avoid.&lt;/p&gt;

&lt;p&gt;A track record can prove that someone made money. It does not prove that their edge survives being copied.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>datascience</category>
      <category>trading</category>
      <category>crypto</category>
    </item>
    <item>
      <title>A published win rate is the actor auditing itself</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Sun, 28 Jun 2026 08:29:06 +0000</pubDate>
      <link>https://dev.to/jugeni/a-published-win-rate-is-the-actor-auditing-itself-190b</link>
      <guid>https://dev.to/jugeni/a-published-win-rate-is-the-actor-auditing-itself-190b</guid>
      <description>&lt;h1&gt;
  
  
  A published win rate is the actor auditing itself
&lt;/h1&gt;

&lt;p&gt;A signal channel that publishes its own win rate is grading its own homework. The number it advertises comes from the part of the record that survived being shown. That does not prove fraud. It proves a measurement problem: the actor writing the record is also the actor being audited. I built the instrument that could see around it, pointed it at the channels everyone screenshots, and this is what it found.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;I build autonomous crypto trading systems in Python. The one running today is live on its own strategies, and has been since June 4, 2026. But before any source earns real capital it has to clear shadow mode first: the full pipeline runs on live market data with realistic frictions, 8bps fees and 5bps slippage, every signal logged as "would have entered at X" and tracked to its outcome, no real order placed.&lt;/p&gt;

&lt;p&gt;Shadow mode is the whole trick. It lets you measure a source against outcomes it does not control, instead of against the receipts it chooses to post.&lt;/p&gt;

&lt;p&gt;Telegram was one of the first sources I wired up. Dozens of crypto signal channels, some with hundreds of thousands of subscribers, many claiming 70 to 80 percent win rates. When the bot connected it pulled in the channel history along with the live feed, so the record reaches back well before the bot existed: 9,312 messages spanning 17 months, February 2025 to June 2026.&lt;/p&gt;

&lt;p&gt;I wanted to measure these channels properly rather than trust the screenshots. I measured them, then I dropped them. This post is the measurement that made that an easy call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pipeline
&lt;/h2&gt;

&lt;p&gt;Most signals never reach evaluation, and where they die is itself the finding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Telegram message received
   -&amp;gt; LLM parsing (DeepSeek): extract pair, side, entry, TP, SL
   -&amp;gt; Staleness check: is the entry still reachable?
   -&amp;gt; Veto filter: RSI sanity, news, Fear and Greed, regime gates
   -&amp;gt; Risk budget: daily loss limit, cooldown, correlation
   -&amp;gt; Shadow execution: log "would have entered at X", track to TP/SL/timeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system tracked 7 channels. Full collection, queried live from the production DB on Jun 27, 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Messages&lt;/th&gt;
&lt;th&gt;Parsed&lt;/th&gt;
&lt;th&gt;Parse fail&lt;/th&gt;
&lt;th&gt;Period&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Crypto_Whales_Pumps_Guide&lt;/td&gt;
&lt;td&gt;2,643&lt;/td&gt;
&lt;td&gt;513&lt;/td&gt;
&lt;td&gt;122&lt;/td&gt;
&lt;td&gt;Feb 2025 - Jun 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binance_Futures_Trades&lt;/td&gt;
&lt;td&gt;2,445&lt;/td&gt;
&lt;td&gt;164&lt;/td&gt;
&lt;td&gt;1,852&lt;/td&gt;
&lt;td&gt;May - Jun 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trading_Crypto_Signals_Bitcoin&lt;/td&gt;
&lt;td&gt;1,808&lt;/td&gt;
&lt;td&gt;164&lt;/td&gt;
&lt;td&gt;1,619&lt;/td&gt;
&lt;td&gt;May - Jun 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cryptoninjas_trading_anm&lt;/td&gt;
&lt;td&gt;1,351&lt;/td&gt;
&lt;td&gt;241&lt;/td&gt;
&lt;td&gt;273&lt;/td&gt;
&lt;td&gt;Jul 2025 - Jun 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tofan_Trade&lt;/td&gt;
&lt;td&gt;1,008&lt;/td&gt;
&lt;td&gt;222&lt;/td&gt;
&lt;td&gt;750&lt;/td&gt;
&lt;td&gt;May - Jun 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;claycryp&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Feb - Jun 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rarecryptosignals&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Feb - Jun 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9,312&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,318&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4,628&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Feb 2025 - Jun 2026&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The gap between &lt;code&gt;Messages&lt;/code&gt; and &lt;code&gt;Parsed + Parse fail&lt;/code&gt; is mostly non-signal content filtered before extraction: chatter, announcements, result posts, teasers, and price updates without tradeable levels.&lt;/p&gt;

&lt;h2&gt;
  
  
  The funnel
&lt;/h2&gt;

&lt;p&gt;Here is what happened to those 9,312 messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;9,312   raw messages received
1,318   parseable (a valid trade idea)        &amp;lt;- 14.2% of raw
  109   timely (still actionable)             &amp;lt;- 8.3% of parseable
   17   reached a trade decision
    0   actually executed                     &amp;lt;- 0%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only 14.2 percent of messages contained a parseable trade idea. The rest was noise: memes, "GM", price alerts without levels, result updates, locked teasers. And of the trade ideas that did parse, only 109 of 1,318 were still actionable by the time my pipeline could act. That is 91.7 percent stale.&lt;/p&gt;

&lt;p&gt;A word on that number, because staleness depends entirely on what you put under the line. The 91.7 percent is timeliness measured against parseable signals: 109 of 1,318. Measured instead against the broader set of candidate messages the pipeline actually ran a staleness check on, it is 97.4 percent: 4,007 of 4,116. Both are real. They answer different questions.&lt;/p&gt;

&lt;p&gt;The number that is wrong is 43 percent, which you get by dividing the stale count by all 9,312 raw messages, quietly swapping a staleness denominator for a raw-volume one. I am showing all three on purpose. The moment you let a single denominator go unstated, you are back to grading your own homework.&lt;/p&gt;

&lt;p&gt;The reason is not slow code. It is that a broadcast channel posts a signal as the move starts, and tens of thousands of people see it at the same instant. By the time anything is parseable and checked, the information is already in the price. Staleness is not a bug in my pipeline. It is the defining property of the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is actually inside the surviving signals
&lt;/h2&gt;

&lt;p&gt;Of the 92 timely signals the router skipped, the rejection codes tell the story:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rejection reason&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;result_message&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;Post-trade update ("TP1 hit") not a new signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;locked_teaser&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;Levels hidden behind a paywall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(no reason)&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;Router skipped without classifying&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Roughly 79 percent of the surviving skipped signals were not signals. They were either announcements of trades already closed or advertisements for the paid tier. I left the unclassified bucket in the table because hiding unknowns would reproduce the exact reporting problem this post is about.&lt;/p&gt;

&lt;p&gt;A locked teaser looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SIGNAL: ETHUSDT SHORT
Entry: [Unlock in Premium]
TP:    [Unlock in Premium]
SL:    [Unlock in Premium]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model can read the pair and the direction. Without levels it is not tradeable. The free tier exists to show you that signals exist, not what they are.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;result_message&lt;/code&gt; half is the same trick from the other side: flood the feed with win announcements to manufacture social proof while the entries stay paywalled. This is the mechanism kenielzep97 described as receipts that are not outcomes, caught in the act. The channel is curating its own track record in real time, and the feed makes the curation read like live flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scorecard, measured against price
&lt;/h2&gt;

&lt;p&gt;The live router executed zero trades. That is the timeliness funnel talking: nothing survived staleness and the veto filters in time to act. Whether the channels had any edge at all is a separate question, so I backtested the parseable signals against historical klines with the same frictions. Only 846 of the 1,318 had klines available to score against, so that is the sample.&lt;/p&gt;

&lt;p&gt;Zero executed is about my pipeline. The scorecard below is about the source. This is the number the channels cannot post, because it comes from outside their reporting loop.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;th&gt;Win%&lt;/th&gt;
&lt;th&gt;Avg PnL&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Crypto_Whales_Pumps_Guide&lt;/td&gt;
&lt;td&gt;646&lt;/td&gt;
&lt;td&gt;46.6%&lt;/td&gt;
&lt;td&gt;+0.52%&lt;/td&gt;
&lt;td&gt;Only statistically meaningful sample&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cryptoninjas_trading_anm&lt;/td&gt;
&lt;td&gt;155&lt;/td&gt;
&lt;td&gt;45.2%&lt;/td&gt;
&lt;td&gt;+0.11%&lt;/td&gt;
&lt;td&gt;Marginal edge, low confidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binance_Futures_Trades&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;40.7%&lt;/td&gt;
&lt;td&gt;-0.22%&lt;/td&gt;
&lt;td&gt;Insufficient sample&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;claycryp&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;85.7%&lt;/td&gt;
&lt;td&gt;+2.70%&lt;/td&gt;
&lt;td&gt;Too small&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rarecryptosignals&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;50.0%&lt;/td&gt;
&lt;td&gt;+0.15%&lt;/td&gt;
&lt;td&gt;Too small&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tofan_Trade&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;-212%&lt;/td&gt;
&lt;td&gt;One RIVERUSDT at -636%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trading_Crypto_Signals_Bitcoin&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;td&gt;Empty signals&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;PnL here is measured against each signal's stop and target model, not a spot buy-and-hold return, so a single bad move on a volatile pair can print below -100 percent. Tofan's -212 percent is one RIVERUSDT trade at -636 percent over n=3, which is a degenerate sample, not a measurement. Only the top two rows have enough trades to mean anything.&lt;/p&gt;

&lt;p&gt;Now put the advertised number next to the measured one, for the two channels where I have both. The advertised figures are the channels' own parsed win rates from an earlier audit; the measured figures are from the backtest above.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Advertised&lt;/th&gt;
&lt;th&gt;Measured&lt;/th&gt;
&lt;th&gt;n (measured)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Crypto_Whales_Pumps_Guide&lt;/td&gt;
&lt;td&gt;78.9%&lt;/td&gt;
&lt;td&gt;46.6%&lt;/td&gt;
&lt;td&gt;646&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cryptoninjas_trading_anm&lt;/td&gt;
&lt;td&gt;76.3%&lt;/td&gt;
&lt;td&gt;45.2%&lt;/td&gt;
&lt;td&gt;155&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I want to be precise about what this gap is and is not. It is not a fabricated win rate. Crypto_Whales actually cleared a positive +0.52 percent average after fees. The gap is survivorship plus staleness: the advertised number is computed over the trades the channel chose to show, after the fact, on a record it authored. The measured number is computed over everything, against prices it did not control.&lt;/p&gt;

&lt;p&gt;Same source, two different records, because two different parties held the pen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The finding the channel cannot see about itself
&lt;/h2&gt;

&lt;p&gt;For Crypto_Whales, the only channel with enough data, breaking down by direction and year:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Side&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;th&gt;Win%&lt;/th&gt;
&lt;th&gt;Avg PnL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;LONG&lt;/td&gt;
&lt;td&gt;365&lt;/td&gt;
&lt;td&gt;46.3%&lt;/td&gt;
&lt;td&gt;+1.06%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;SHORT&lt;/td&gt;
&lt;td&gt;86&lt;/td&gt;
&lt;td&gt;54.7%&lt;/td&gt;
&lt;td&gt;+1.83%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026&lt;/td&gt;
&lt;td&gt;LONG&lt;/td&gt;
&lt;td&gt;120&lt;/td&gt;
&lt;td&gt;28.3%&lt;/td&gt;
&lt;td&gt;-2.23%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026&lt;/td&gt;
&lt;td&gt;SHORT&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;td&gt;68.0%&lt;/td&gt;
&lt;td&gt;+0.77%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;SHORTs beat LONGs in both years, and the 2026 LONG collapse tracks a regime shift where altcoin longs got crushed. The edge in the data was on the short side. The channel brands itself as a "whale pump" tracker, which points its readers at longs. The free tier was advertising the opposite direction to where the measured edge actually was.&lt;/p&gt;

&lt;p&gt;Not out of malice. The channel has no way to know this, because it never measures its own outcomes against price. It only sees the trades it posted.&lt;/p&gt;

&lt;p&gt;This is the whole point. Without tagging BTC regime at the moment each signal arrived, the 2026 collapse would have looked like the channel getting worse. With it, you can see it was a regime effect that any long-biased source would have suffered. Regime context only exists if you stamp it at signal time. Reconstruct it afterward and you inherit the same blind spot as the channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a published win rate cannot audit itself
&lt;/h2&gt;

&lt;p&gt;Every layer here is the same shape. The channel decides which trades to announce and also reports on how those trades did. The decider and the reporter are the same party, so the record is flattering by construction, the same way a compliance checker that keeps signing off on its own work looks clean to everything downstream.&lt;/p&gt;

&lt;p&gt;Arpit Gupta put the general version of it well: any system where the component that decides to act is also the component that reports on whether it should have is structurally blind to this exact failure.&lt;/p&gt;

&lt;p&gt;The only reason I could see any of it is that the measurement lived somewhere the channel could not write to. Shadow mode against real prices is the external observer. Pull that out and you are left grading the channel on the channel's own receipts, which is no measurement at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I moved on
&lt;/h2&gt;

&lt;p&gt;In May 2026 I deprecated Telegram as a source and pivoted to bot-footprint signals: liquidation cascades, open-interest surges, funding divergence, on-chain whale tape.&lt;/p&gt;

&lt;p&gt;The intuition is to stop following what channels say and start following what large traders actually do, as revealed by their market footprint. A footprint is a consequence the actor cannot author. A win-rate screenshot is a record the actor authors completely.&lt;/p&gt;

&lt;p&gt;The 97 percent staleness rate is empirical evidence that by the time a broadcast reaches you, the information is usually already priced in.&lt;/p&gt;

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

&lt;p&gt;I did not prove the channels lie. I proved that the record I was allowed to check was incomplete in exactly the direction that makes the source look safer than it is. The advertised win rate is real, in the same way a green screenshot is real. It is a true record of the moments someone chose to write down.&lt;/p&gt;

&lt;p&gt;The outcome is what happens after the last update, and that is the part nobody posts.&lt;/p&gt;

&lt;p&gt;If you publish the win rate, you do not get to be the audit of it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update — July 2, 2026.&lt;/strong&gt; I ran a hostile agent over my own posts to find what is false, not to polish them. It flagged two things here that need correcting. Full writeup: "Every Post I Publish Gets AI Review" (&lt;a href="https://dev.to/jugeni/every-post-i-publish-gets-ai-review-a-hostile-agent-still-found-the-holes-in-twenty-minutes-6e"&gt;https://dev.to/jugeni/every-post-i-publish-gets-ai-review-a-hostile-agent-still-found-the-holes-in-twenty-minutes-6e&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The 97.4% staleness figure is an artifact, not a second valid measurement.&lt;/strong&gt; I wrote that staleness is 91.7% against parseable signals (109/1,318) and 97.4% against a broader denominator (4,007/4,116), and that "both are real." The 97.4% is not real in the way I implied. Those 4,007 stale rows come from a one-time relabel I ran on 2026-05-18, not from the pipeline detecting staleness live. There are no organically stale rows after that date. The number that stands is 91.7%. Read the 97.4% as a maintenance artifact and disregard it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The "Advertised" column is my own number, not the channels'.&lt;/strong&gt; I described the advertised figures as "the channels' own parsed win rates from an earlier audit." That is wrong. Both columns are mine: "Advertised" is my earlier backtest measured as TP1 first-touch, "Measured" is a fixed-horizon mark-to-market with no take-profit, stop-loss, or fees. The gap is between two of my own measurement conventions, not between a channel's claim and my result. That weakens the "channels vs reality" reading, and I should not have framed it that way.&lt;/p&gt;

&lt;p&gt;Leaving the original text below unchanged, so the record of the mistake stays visible. A published record is the actor auditing itself. Here the actor got audited.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>crypto</category>
      <category>trading</category>
      <category>llmops</category>
    </item>
    <item>
      <title>My trading bot said it was trading for four days... he was lying</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Thu, 25 Jun 2026 18:11:32 +0000</pubDate>
      <link>https://dev.to/jugeni/60-of-my-921-wasnt-strategy-the-other-40-wasnt-even-visible-4m30</link>
      <guid>https://dev.to/jugeni/60-of-my-921-wasnt-strategy-the-other-40-wasnt-even-visible-4m30</guid>
      <description>&lt;p&gt;Twenty-five days on Hyperliquid. Sixty-five closed trades. P&amp;amp;L: -$9.21.&lt;/p&gt;

&lt;p&gt;Turns out that was the smallest wrong thing about it.&lt;/p&gt;

&lt;p&gt;The landing page showed -$7.72 because it uses a different P&amp;amp;L formula and excludes two open positions. Either number is small. Both numbers were also wrong about what they were telling me.&lt;/p&gt;

&lt;p&gt;I spent yesterday auditing every trade. The audit produced three findings I did not expect. Each one was a different kind of wrong.&lt;/p&gt;

&lt;p&gt;This is the first post in a series about &lt;strong&gt;ziom trader&lt;/strong&gt;, my small AI-assisted crypto trading bot. "Ziom" is Polish for buddy, mate, or dude depending on who's talking. The name is unserious on purpose. The system is not.&lt;/p&gt;

&lt;p&gt;This is not a "watch me print money" series. The number is negative. Good.&lt;/p&gt;

&lt;p&gt;The point of the series is to track what happens when an LLM-assisted trading system moves from backtests and dashboards into live execution: where the bot is wrong, where the dashboard is wrong, where I am wrong, and which layer gets to prove it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frame
&lt;/h2&gt;

&lt;p&gt;The natural first read of -$9.21 is "the strategy is losing money." That read assumes the displayed P&amp;amp;L attributes to the strategy. It does not.&lt;/p&gt;

&lt;p&gt;The number that shows up at the surface is the sum of at least three different layers: the strategy itself, the execution wrapper around it, and the monitoring layer that observes both. Each layer can author its own kind of failure. The displayed number compresses all three into a single dollar figure and loses the attribution on the way up.&lt;/p&gt;

&lt;p&gt;The framing that landed for me, from Daniel Nevoigt, is that methodology overview without forward-correlation disclosure is a log with good intentions. Same applies to P&amp;amp;L: total P&amp;amp;L without layer-attribution disclosure is a log with good intentions. You see the number. You do not see where it came from.&lt;/p&gt;

&lt;p&gt;Here is what I found when I forced the attribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Shadow does not equal live
&lt;/h2&gt;

&lt;p&gt;Before deploying any lane, the system runs against backtested data. The shadow says "this strategy returns X over Y trades." The deploy decision is taken when the shadow looks healthy. The live then runs and produces a different number.&lt;/p&gt;

&lt;p&gt;The label for that difference is not "the strategy disappointed." The shadow is one authority. The live is a different authority. The market authored the failure criterion, not the strategy.&lt;/p&gt;

&lt;p&gt;This is the version of the seam Christopher Maher named: the bite check did not catch itself, a different rail caught it. Shadow data cannot author its own failure. Only the live market can. And the live market does not tell you which part of the gap is variance, which part is regime drift, and which part is a parameter you forgot to tune.&lt;/p&gt;

&lt;p&gt;In this window the funding_divergence_long lane had a shadow edge of +0.355%/trade across n=660 backtested trades, CI95 [+0.085, +0.625]. The live for the same lane was -1.10% / trade across 29 live trades. The gap is 1.46 percentage points. At sigma about 2% per trade and n=29, that gap is 3.9 standard errors. Statistically significant negative.&lt;/p&gt;

&lt;p&gt;That does not prove the strategy is broken. It proves the shadow and the live disagreed by more than variance would explain. Three explanations remain in play, and the audit can narrow but not resolve them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;June 15 ADA outlier was -$2.25, -5.64%, which is 3.6 sigma from shadow mean. One trade is doing structural work in a small sample.&lt;/li&gt;
&lt;li&gt;Edge is not durable across this BTC window. June saw recovery to reversal.&lt;/li&gt;
&lt;li&gt;Exit configuration choices let losers run.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;50 to 100 more trades are needed to separate these. I am not separating them today. The label for this section is AMBIGUOUS and I am pinning it to that label until the sample doubles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Live displayed does not equal strategy true
&lt;/h2&gt;

&lt;p&gt;Inside the -$9.21, 60% is not strategy. It is system overhead with git commit refs.&lt;/p&gt;

&lt;p&gt;The breakdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Trades&lt;/th&gt;
&lt;th&gt;Loss&lt;/th&gt;
&lt;th&gt;Commit ref&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;oi_surge LONG with no regime gate, ran in bear&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;-$1.45&lt;/td&gt;
&lt;td&gt;gate added &lt;code&gt;2d10e326&lt;/code&gt; Jun 11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;whale lane missing max_per_coin cap&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;-$0.95&lt;/td&gt;
&lt;td&gt;cap added &lt;code&gt;5bd9eaaf&lt;/code&gt; Jun 9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;whale_footprint as dead lane before disarm&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;-$2.71&lt;/td&gt;
&lt;td&gt;disarmed &lt;code&gt;18d937aa&lt;/code&gt; Jun 13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;oi_surge LONG as dead lane, 1 trade Jun 12&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;-$0.38&lt;/td&gt;
&lt;td&gt;not explicitly disarmed in this window&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total system overhead: -$5.49 across 36 trades, 60% of the loss.&lt;/p&gt;

&lt;p&gt;Sixty percent of the loss has an audit trail. Most of it has a git commit. All of it is a different kind of wrong than "the signal failed."&lt;/p&gt;

&lt;p&gt;Each line has either a commit hash that closes the gap or a seam that the audit made visible. None of it is the strategy in the sense of "the signal was wrong." All of it is the system in the sense of "the rail that would have stopped this did not exist yet."&lt;/p&gt;

&lt;p&gt;Sean Burn names it right: show the seam, do not hide it. Show that 60% of this loss is closed by commits that exist now and did not exist on June 6. Do not collapse "system" and "strategy" into one bucket called "the bot lost money." They are different authors of the same dollar.&lt;/p&gt;

&lt;p&gt;The remaining 40% is funding_divergence_long (-$4.15 across 32 trades) and oi_surge_fade (+$0.13 across 2 trades). The funding_long line is the one with the shadow-vs-live gap from Layer 1. Without the ADA outlier and without the execution gap I will describe next, the lane runs at -$1.47 across 28 trades, or -$0.05 / trade. That is noise floor for this sample size, not strategy quality. Treat it that way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Visible live does not equal what the driver attempted
&lt;/h2&gt;

&lt;p&gt;The third finding had no warning. The first two were inventory work. This one was structural.&lt;/p&gt;

&lt;p&gt;Between June 18 10:01 UTC and June 22 16:01 UTC, the funding_divergence_long driver was armed. The &lt;code&gt;run_summary&lt;/code&gt; events in the database show &lt;code&gt;armed=true, placed=1&lt;/code&gt; for the entire 4-day window, roughly 20 to 30 cycles. The positions table for the same window shows zero new fills. The events table shows zero &lt;code&gt;execution_error&lt;/code&gt; events.&lt;/p&gt;

&lt;p&gt;The dashboard read &lt;code&gt;placed=1&lt;/code&gt;. The exchange acknowledgement layer wrote &lt;code&gt;placed_ok=0&lt;/code&gt;. The error path that would have written an &lt;code&gt;execution_error&lt;/code&gt; row never ran, because the code that throws the exception was caught somewhere upstream without incrementing the error counter.&lt;/p&gt;

&lt;p&gt;For four days, the driver said it was trading. The exchange said it was not.&lt;br&gt;
The events table said nothing.&lt;/p&gt;

&lt;p&gt;The audit trail itself was lying.&lt;/p&gt;

&lt;p&gt;The framing from L. Cordero applies: trust retrieval, verify recall. The &lt;code&gt;placed=1&lt;/code&gt; counter was the system retrieving its own belief. The actual position state was the recall, and the recall path was broken. The two layers diverged silently, and the dashboard was reading the wrong one.&lt;/p&gt;

&lt;p&gt;The framing from Todd Hendricks applies: big number, wrong metric. &lt;code&gt;placed=1&lt;/code&gt; is a big number. &lt;code&gt;placed_ok=0&lt;/code&gt; is the meaningful one. The system displayed the big one. I deployed the wrong dashboard.&lt;/p&gt;

&lt;p&gt;The fix landed today, after the audit, after a peer who runs a different read-the-chain product confirmed independently that the seam between an attempted read and a verified read is where this class of bug lives. His phrase for the right default: incomplete by default. Anything not explicitly classified as a verified result is unknown, not zero. Zero and unknown render visually distinct. The pipeline carries the distinction all the way to the surface.&lt;/p&gt;

&lt;p&gt;Impact ESTIMATED: 20 to 30 missed signals, ~$15 notional each. If the shadow edge held, plus or minus $1 to $1.50 in either direction, gain or loss, invisible to the displayed P&amp;amp;L. The honest label is ESTIMATED because I cannot know which way the missed trades would have gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the audit changes
&lt;/h2&gt;

&lt;p&gt;The displayed loss is -$9.21. The strategy contribution to that loss, after subtracting system overhead and the execution gap and the single 3.6-sigma outlier, is approximately -$1.47 across 28 trades, or -$0.05 per trade. That is noise. The sample is too small to call the strategy good or bad. Forward-test budget: 50 to 100 more trades before any strategy-quality verdict.&lt;/p&gt;

&lt;p&gt;The system overhead is closed. The commits exist. The next 50 to 100 trades will run with the regime gate, the max_per_coin cap, the disarmed dead lanes, the corrected verification rail, and the current active lane configuration. If those run and the lane is still -$0.10/trade or worse, the strategy is the problem, not the rails. If they run and the lane comes in at +$0.05/trade or better, the shadow edge held and the previous loss was the rails.&lt;/p&gt;

&lt;p&gt;I am locking the test budget in advance: if the next 50 trades come in at -$0.10/trade or worse, I retract the post-fix optimism in this post. The bet is on the rails being the issue, not the signal. I will publish the next breakdown either way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Post-audit check
&lt;/h2&gt;

&lt;p&gt;Added 2026-06-25 around 19:15 CEST, roughly 12 hours after the audit opened. I checked.&lt;/p&gt;

&lt;p&gt;The first post-audit window did not reproduce the previous failure pattern.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;oi_surge_fade_live&lt;/code&gt; SHORT lane produced approximately +$1.38 across 12 post-audit trades, with 10 of 12 green.&lt;/p&gt;

&lt;p&gt;That includes AVAX, UNI, ADA, ATOM, FIL, and TIA. The important part is not that the number is green. The important part is that the result came after the audit separated attempted placement from exchange-confirmed placement.&lt;/p&gt;

&lt;p&gt;The early read is positive, but narrow.&lt;/p&gt;

&lt;p&gt;This is not "the fixes worked." It is "the first post-audit window did not immediately repeat the old bug shape, and the active lane produced a green early window under the new reporting rail."&lt;/p&gt;

&lt;p&gt;Those are different claims.&lt;/p&gt;

&lt;p&gt;I am only making that narrow claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not a how-I-made-money post. The number is negative. It is not large. The strategy is unverified. The audit caught real bugs with commit refs but did not prove the strategy works.&lt;/p&gt;

&lt;p&gt;This is also not a how-AI-coded-my-bot post. Claude Code wrote large parts of this system. The audit found multiple places where the same author, me with model assistance, wrote both the action layer and the layer that was supposed to verify the action. Single-author audit trails lie. That part is on the system design, not on the model.&lt;/p&gt;

&lt;p&gt;What this is, is the breakdown that should sit underneath any small displayed number from any algorithmic trading or autonomous agent system. Three different kinds of wrong. Three different authors of the same dollar. The displayed number is one of them. The other two are invisible by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Series contract
&lt;/h2&gt;

&lt;p&gt;This series will track &lt;strong&gt;ziom trader&lt;/strong&gt; as a live system, not as a performance claim.&lt;/p&gt;

&lt;p&gt;I will publish the boring parts: small losses, missed fills, broken counters, stale assumptions, dashboard lies, audit fixes, and retractions when the next sample contradicts the previous read.&lt;/p&gt;

&lt;p&gt;No alpha claims. No "the bot works" until the forward sample earns that sentence. No hiding the layer that authored the failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Peer credits
&lt;/h2&gt;

&lt;p&gt;The vocabulary that made this audit possible came from people writing about adjacent problems in adjacent domains.&lt;/p&gt;

&lt;p&gt;None of these people were writing about trading bots. Some were writing about incident reports, some about agent systems, one about a read-chain product.&lt;/p&gt;

&lt;p&gt;The overlap was not planned. That's the point.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Daniel Nevoigt: "methodology overview without forward-correlation disclosure is a log with good intentions"&lt;/li&gt;
&lt;li&gt;Christopher Maher: "the bite check did not catch itself, a different rail caught it"&lt;/li&gt;
&lt;li&gt;L. Cordero: "trust retrieval, verify recall"&lt;/li&gt;
&lt;li&gt;Sean Burn: "show the seam, do not hide it"&lt;/li&gt;
&lt;li&gt;Todd Hendricks: "big number, wrong metric"&lt;/li&gt;
&lt;li&gt;TxDesk, ratifying the placed=1/placed_ok=0 framing in a different domain this morning: "incomplete by default"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I am leaving the credits in the post. The vocabulary did not decorate the audit. It changed what the audit could see.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can take from this
&lt;/h2&gt;

&lt;p&gt;If you run a live system, look for the layer where your own code writes both the action and the verification. That is where this class of bug lives. The fix is not only better testing. The fix is making the action layer and the verification layer be authored by different code paths, ideally by different authors, with the verification path explicitly classifying anything it did not see as incomplete by default.&lt;/p&gt;

&lt;p&gt;Render the difference, not the success. Five attempted and three succeeded is a normal display state. Five attempted and unknown succeeded is the state your dashboard probably hides today.&lt;/p&gt;

&lt;p&gt;That is the line the audit drew.&lt;/p&gt;

&lt;p&gt;If you are the bot, you do not get to be the auditor.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>crypto</category>
      <category>trading</category>
      <category>agents</category>
    </item>
    <item>
      <title>I built jugeni two weeks ago and I have no idea what it does anymore</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Wed, 24 Jun 2026 19:20:14 +0000</pubDate>
      <link>https://dev.to/jugeni/i-built-jugeni-two-weeks-ago-and-i-have-no-idea-what-it-does-anymore-3234</link>
      <guid>https://dev.to/jugeni/i-built-jugeni-two-weeks-ago-and-i-have-no-idea-what-it-does-anymore-3234</guid>
      <description>&lt;h1&gt;
  
  
  I built jugeni two weeks ago and I have no idea what it does anymore
&lt;/h1&gt;

&lt;p&gt;I sat down to write a feature post about jugeni.&lt;/p&gt;

&lt;p&gt;I have used it every day for two weeks. I cannot describe what it does anymore.&lt;/p&gt;

&lt;p&gt;That sounds like a failure of positioning. It may be the point.&lt;/p&gt;

&lt;p&gt;Every time I try to name a feature, I realize I have not consciously touched that layer in days. The recap is just there. The decision is already locked. The compact gate says no before I waste another context window. The note is saved before I remember I should save it.&lt;/p&gt;

&lt;p&gt;A tool you can describe is still asking for attention.&lt;/p&gt;

&lt;p&gt;A tool you forget may have become infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened when I tried to write the feature list
&lt;/h2&gt;

&lt;p&gt;I opened my own notes. Half of them I do not remember writing.&lt;/p&gt;

&lt;p&gt;The decisions ledger: I opened it yesterday to lock a decision, found out the decision was already locked, by me, three days ago. I do not remember locking it.&lt;/p&gt;

&lt;p&gt;The vendor stack: I have not had to ask “where are we with the bank paperwork?” in four days. The reminder surfaces in the main thread, on its own, when the state changes. I type &lt;code&gt;jugeni recap&lt;/code&gt; only when I want the wider view. The mental energy I used to spend reconstructing context is gone, and I did not notice when it left.&lt;/p&gt;

&lt;p&gt;The compact gate: this afternoon I tried to run &lt;code&gt;/compact&lt;/code&gt; and a hook blocked it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;5h burn 60%, compact would cost another 7%, denied.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That line means the session had already burned 60% of its useful working context after five hours.&lt;/p&gt;

&lt;p&gt;I noticed the block after I read the hook log, not in the moment. The decision was made for me. I would have approved it if I had been asked. I was not asked.&lt;/p&gt;

&lt;p&gt;That is the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  The paradox
&lt;/h2&gt;

&lt;p&gt;A tool you can describe is a tool you still have to think about.&lt;/p&gt;

&lt;p&gt;The act of writing a feature post is evidence that the feature is not yet smooth. The post you can write about your tool is the post about the layer that has not yet disappeared into the work.&lt;/p&gt;

&lt;p&gt;Which makes this post structurally awkward, and also kind of the joke.&lt;/p&gt;

&lt;p&gt;I have been writing about this property for operators for a few weeks. The operators worth trusting are the ones whose operating disappears into the result. You do not see the work. You see the work landing. The smooth is the absence of the seam.&lt;/p&gt;

&lt;p&gt;I did not expect to land in the same property from the other side.&lt;/p&gt;

&lt;p&gt;Tools that disappear into the operator’s work share that shape. The thing you can name is the thing you have not yet absorbed. The thing you cannot name is doing some of the work for you.&lt;/p&gt;

&lt;p&gt;Which means the success metric for jugeni is hostile to writing a feature page. Every absorbed feature is one that resists description. Every describable feature is one I am still actively driving.&lt;/p&gt;

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

&lt;p&gt;I notice jugeni only when it breaks.&lt;/p&gt;

&lt;p&gt;A note that did not save. A recap that missed a thread. A hook that fired at the wrong moment. A decision that should have been surfaced and was not.&lt;/p&gt;

&lt;p&gt;Failure is the only feedback channel I have for the parts that work.&lt;/p&gt;

&lt;p&gt;That is a problem worth saying out loud. I do not know what jugeni is silently failing at. Smooth is also where audit becomes hardest. The same property that makes infrastructure good at carrying work makes it bad at announcing its own gaps.&lt;/p&gt;

&lt;p&gt;Then the problem recurses. If the tool disappears, the audit layer also has to be quiet. But if the audit layer is quiet, I need a way to know when it failed.&lt;/p&gt;

&lt;p&gt;I do not have an answer for this yet.&lt;/p&gt;

&lt;p&gt;I have a habit of writing down what I noticed when something broke, and that habit is itself a thread in jugeni. So the tool catches some of its own failures by feeding them back into the same ledger.&lt;/p&gt;

&lt;p&gt;That is not a proof.&lt;/p&gt;

&lt;p&gt;It is a floor, and I will take it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is, for now
&lt;/h2&gt;

&lt;p&gt;Two weeks ago jugeni was a folder with three Markdown files and a shell alias.&lt;/p&gt;

&lt;p&gt;It is now infrastructure for the way I work.&lt;/p&gt;

&lt;p&gt;Plain Markdown notes. Flat files. No database. A decisions ledger. Active threads. Hooks for budget and compaction. Recaps over vendor state and project state. Status fields that survive the session boundary. Enough boring scaffolding that I can stop reconstructing context from memory.&lt;/p&gt;

&lt;p&gt;The strange part is not that any single feature is complicated.&lt;/p&gt;

&lt;p&gt;The strange part is that the tool became less visible as the pieces started carrying each other.&lt;/p&gt;

&lt;p&gt;I did not feel the transition.&lt;/p&gt;

&lt;p&gt;I would not have noticed it if I had not tried to write the post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;If you built infrastructure that disappeared, you probably built something right.&lt;/p&gt;

&lt;p&gt;If you can still feel it working, it is not done.&lt;/p&gt;

&lt;p&gt;I sat down to describe jugeni and mostly found the shape of what had stopped asking for my attention.&lt;/p&gt;

&lt;p&gt;I think that is the post.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;jugeni is a CLI for operator-side discipline: notes, decisions, recaps, hooks, and session state that survive the chat window. Plain Markdown notes, flat files, no database. Two weeks old, currently at 250+ notes, around 30 locked decisions, and 12 active threads. Source release planned once the edges stop moving daily.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>A Verifier Role Is Not a Verified Verifier</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Wed, 24 Jun 2026 10:03:38 +0000</pubDate>
      <link>https://dev.to/jugeni/a-verifier-role-is-not-a-verified-verifier-4jdg</link>
      <guid>https://dev.to/jugeni/a-verifier-role-is-not-a-verified-verifier-4jdg</guid>
      <description>&lt;h2&gt;
  
  
  TRINITY ships a Verifier role. Did anyone test it?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The field is shipping Verifier roles faster than it's shipping Verifier testing.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://sakana.ai/fugu/" rel="noopener noreferrer"&gt;Sakana AI&lt;/a&gt; just put two things on the table at once. &lt;strong&gt;&lt;a href="https://arxiv.org/abs/2512.04695" rel="noopener noreferrer"&gt;TRINITY&lt;/a&gt;&lt;/strong&gt; — an ICLR 2026 paper that formalizes a coordinator over a pool of LLMs, with one of the assigned roles called &lt;strong&gt;Verifier&lt;/strong&gt;. And &lt;strong&gt;&lt;a href="https://sakana.ai/fugu/" rel="noopener noreferrer"&gt;Fugu&lt;/a&gt;&lt;/strong&gt; — a production multi-agent orchestration system delivered as a single OpenAI-compatible endpoint, presented as the direction Sakana's research is heading toward product. The &lt;a href="https://arxiv.org/abs/2606.21228" rel="noopener noreferrer"&gt;Fugu technical report&lt;/a&gt; covers the orchestration design choices and benchmark methodology.&lt;/p&gt;

&lt;p&gt;This is the moment agent verification stops being an afterthought and becomes a named, first-class role in a paper from a top-tier lab. That matters. So does what's missing from the evaluation.&lt;/p&gt;

&lt;p&gt;This is not a critique of Sakana's results. It is a narrower question, and the cleanest way I can put it is this: &lt;strong&gt;a role label is a declaration of architecture, not evidence of capability.&lt;/strong&gt; Once a system names a Verifier role, what evidence would show that the verifier detects planted errors rather than just participates in orchestration?&lt;/p&gt;

&lt;h2&gt;
  
  
  What TRINITY names
&lt;/h2&gt;

&lt;p&gt;Section 3.2 of the &lt;a href="https://arxiv.org/abs/2512.04695" rel="noopener noreferrer"&gt;TRINITY paper&lt;/a&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The verifier checks whether the accumulated solution in 𝒞_{k−1} is correct, complete, and responsive to Q. It outputs a judgment u_k ∈ {ACCEPT, REVISE} and an optional diagnosis δ_k.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the contract. The Verifier consumes the accumulated transcript and the original query, returns a binary judgment, and may offer a diagnosis. The role is invoked by the coordinator, which assigns it to one of seven candidate models (GPT-5, Gemini-2.5-pro, Claude-4-Sonnet, and four open-source models).&lt;/p&gt;

&lt;p&gt;Two things the paper does not specify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Against what independent reference does the Verifier check correctness?&lt;/strong&gt; The transcript and the query are both inside the loop. There's no external ground truth, no held-out spec, no second-channel oracle. The Verifier is checking the system's own output against the system's own restatement of the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whether the Verifier shares a base model with the Thinker or Worker.&lt;/strong&gt; The paper describes role-to-model assignment as something the coordinator learns, but does not specify whether the same model can be assigned Thinker and Verifier in the same run. In a seven-model pool, the probability of role overlap across rounds is not negligible. If GPT-5 is the Thinker on round k and the Verifier on round k+1, the second opinion shares a brain with the first.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://arxiv.org/abs/2606.21228" rel="noopener noreferrer"&gt;Fugu technical report&lt;/a&gt; adds a related design choice for the latency-aware variant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The selected model is always invoked as a worker, which reduces the coordination space and lowers orchestration latency.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So in the latency-aware Fugu variant described there, roles are dropped: the selected model is always invoked as a worker. Fugu-Ultra, the quality-first variant, leans on multi-agent coordination with isolation through access lists. &lt;strong&gt;The TRINITY Verifier primitive is the research artifact. The production system has chosen, for one variant, to drop roles for latency reasons.&lt;/strong&gt; That's a signal in itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The work is impressive
&lt;/h2&gt;

&lt;p&gt;Before the gap, the receipts. Fugu lands real wins on Sakana's benchmark page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rubik's Cube Solver:&lt;/strong&gt; Fugu-Ultra solves all 300 cubes; every other frontier model returns zero valid solutions. That is actual domination, not statistical noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Classical Japanese Text:&lt;/strong&gt; Fugu-Ultra at NED 0.80 versus 0.24 for the next best competitor. More than 3× better on a language task most frontier models barely engage with.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SWE Bench Pro:&lt;/strong&gt; Fugu Ultra 73.7 vs Opus 4.8 at 69.2. A 4.5-point margin on a hard software-engineering benchmark.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are real numbers and they take real engineering. The same calibration gap that this post is about also shows up in benchmark interpretation: Fugu's blindfold-chess result is against Stockfish set to 2100 Elo, honest in the paper and flattened in the social-media echo. The receipts are real; the framing they travel with is the part that needs reading carefully.&lt;/p&gt;

&lt;p&gt;The question is narrower: whether the Verifier role inside the orchestration is doing work, or whether the end-task accuracy is rising for reasons that have nothing to do with verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark wins are not Verifier tests
&lt;/h2&gt;

&lt;p&gt;End-task accuracy and verifier reliability are not the same measurement. A system can post strong benchmark numbers because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the Thinker and Worker are individually strong frontier models, and the coordinator routes them well&lt;/li&gt;
&lt;li&gt;the model pool diversifies failure modes through routing, not through verification&lt;/li&gt;
&lt;li&gt;the Verifier rubber-stamps most outputs, and the small number of REVISE rounds happen to catch the cases that matter&lt;/li&gt;
&lt;li&gt;the Verifier never rejects, and the system still wins because the Workers are already good enough&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all four cases, the benchmark goes up. In only one of them is the Verifier doing what the role name suggests. There's no way to distinguish them from end-task accuracy alone.&lt;/p&gt;

&lt;p&gt;This is the same shape as devto-09's argument about quorum verification: independence is the assumption nobody verifies. Here it's one floor up. A Verifier role that's never tested under planted errors is not a verifier — it's a third opinion participating in orchestration. That can still be useful. It's not what the word &lt;em&gt;verifier&lt;/em&gt; promises.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tool-use moves the verification boundary, it doesn't remove it
&lt;/h2&gt;

&lt;p&gt;Here's the natural objection outside the chess example: &lt;em&gt;but agentic systems can write code, call tools, run solvers, and check outputs. The model doesn't need to calculate everything internally; the tool can do the calculation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Correct. And that is exactly where the verification boundary has to move — not disappear.&lt;/p&gt;

&lt;p&gt;Fugu's blindfold chess example is actually the opposite case: the technical report says the task does not use an agentic scaffold, every model is queried directly through its bare API, and the board is never restated. That makes the chess result a cleaner long-context and state-tracking result, not a tool-use result. Worth flagging, because the social-media echo around "LLM beats Stockfish" sometimes assumes the opposite.&lt;/p&gt;

&lt;p&gt;But in the broader TRINITY/Fugu direction — coding, AutoResearch, CAD, tool-using agent workflows — tool augmentation introduces three new failure modes, each of which needs its own verification:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The agent writes buggy tool code.&lt;/strong&gt; Off-by-one indexing, wrong constant, swapped variable in the cost function. The tool runs without raising an exception. The output is silently wrong. End-task accuracy on a held-out test might still look fine if the bug doesn't trigger on the test distribution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The agent misparses tool output.&lt;/strong&gt; The tool returns the correct answer. The agent transcribes it as something close but wrong — a digit, a sign, a unit. The tool worked correctly. The integration boundary broke.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The agent routes to the wrong tool, or at the wrong moment.&lt;/strong&gt; Asked about A, calls a tool for B. Asked about B, tries to reason from training data instead of calling the tool that exists. Routing is a model-side decision and can be fluky in long-context, multi-step pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;TRINITY's Verifier checks the final accumulated solution against the original query. It does not — in the contract as written — check tool-call provenance, parse fidelity, or routing decisions. &lt;strong&gt;If the agent silently garbles in the middle of the pipeline and the final answer still pattern-matches the expected shape, the Verifier returns ACCEPT.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Single point of failure wearing a tool-augmented quorum costume. Same shape as the verification gap in non-tool agents, with more boundaries that need their own planted-fault tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  The missing experiment: planted Verifier faults
&lt;/h2&gt;

&lt;p&gt;What would it take to actually evaluate the Verifier role? These are not moonshot experiments. They are appendix-sized evaluations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Detection power.&lt;/strong&gt; Take 200 examples from a benchmark TRINITY already runs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feed the Verifier the &lt;em&gt;correct&lt;/em&gt; solution. Measure ACCEPT rate. Should be near 1.0.&lt;/li&gt;
&lt;li&gt;Feed the Verifier a &lt;em&gt;subtly wrong&lt;/em&gt; solution: off-by-one, wrong constant, swapped variable, plausible structure with a flipped sign somewhere. Measure REJECT rate. A real verifier should reject most of these.&lt;/li&gt;
&lt;li&gt;Feed the Verifier a &lt;em&gt;plausible-but-irrelevant&lt;/em&gt; solution: well-formatted answer to a different question. Measure REJECT rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A Verifier that ACCEPTs all three categories at similar rates is not detecting anything. It's voting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Independence test.&lt;/strong&gt; Run the same 200 examples twice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verifier uses the &lt;em&gt;same base model&lt;/em&gt; as the Thinker on the round being checked.&lt;/li&gt;
&lt;li&gt;Verifier uses a &lt;em&gt;different base model&lt;/em&gt; — different family, different pretraining data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare REJECT rates on the planted-wrong condition. If they're the same, role assignment isn't load-bearing — the Verifier behaves the same way regardless of whether it shares a brain with the Thinker. If the cross-family Verifier rejects more, independence is doing real work and should be promoted from a soft preference to a hard constraint in role assignment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Tool-boundary test.&lt;/strong&gt; For pipelines that use tools, plant errors at the boundary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correct tool call, correct output, &lt;em&gt;mistranscribed&lt;/em&gt; into the transcript.&lt;/li&gt;
&lt;li&gt;Wrong tool selected, plausible output, &lt;em&gt;passed forward as if correct&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Buggy tool code that produces consistent-looking but wrong results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Measure how often the Verifier catches each. A Verifier that only checks the final accumulated solution and not the pipeline that produced it will miss most of these by construction.&lt;/p&gt;

&lt;p&gt;None of these experiments require new infrastructure. They require deciding to run them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern is structural
&lt;/h2&gt;

&lt;p&gt;The pattern shows up in several independent stacks within a single week. A second-view discipline in agentic IDE tooling. A verifier shape with cadence and externally-authored constraints in another operator's open framework. An apply/advisory split in a third. Now an explicit Verifier role in a frontier lab's ICLR paper, paired with a production endpoint.&lt;/p&gt;

&lt;p&gt;The vocabularies differ. The shape is the same. &lt;strong&gt;At every layer, the system names verification, and at no layer is the verifier itself tested as if it could be wrong.&lt;/strong&gt; The role label is doing the work the capability evidence has not yet been asked to do.&lt;/p&gt;

&lt;p&gt;This isn't a coordination problem. It's a category gap: the field's verifiers are evaluated by the same kind of evidence — end-task accuracy — that they're supposed to provide independent commentary on. When the verifier and the system it verifies are scored by the same metric, there's no room for the verifier to disagree usefully. ACCEPT becomes the equilibrium.&lt;/p&gt;

&lt;p&gt;Devto-09 named this one floor below: independence is the assumption nobody verifies. TRINITY is the same gap one floor up, with a name on it. Naming the role doesn't close the loop. Testing the role under planted faults does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Close
&lt;/h2&gt;

&lt;p&gt;Credit where it is due. The Sakana AI team did the field a service by making the Verifier a first-class role in &lt;a href="https://arxiv.org/abs/2512.04695" rel="noopener noreferrer"&gt;TRINITY&lt;/a&gt;, and by shipping &lt;a href="https://sakana.ai/fugu/" rel="noopener noreferrer"&gt;Fugu&lt;/a&gt; as a production-grade multi-agent endpoint with the &lt;a href="https://arxiv.org/abs/2606.21228" rel="noopener noreferrer"&gt;technical report&lt;/a&gt; attached. Both artifacts move the conversation forward. The next move is testing the Verifier as one. The experiments above are small, public, and reproducible against the seven-model pool the paper already uses.&lt;/p&gt;

&lt;p&gt;Until then, every benchmark win where a Verifier was in the loop carries an asterisk. The system worked. Whether the Verifier inside the system worked is a separate question, and it has not been asked yet.&lt;/p&gt;

&lt;p&gt;A role label is a declaration of architecture. A planted-fault eval is the cheapest possible piece of evidence that the architecture is doing what the label claims. The field is shipping Verifier roles faster than it's shipping Verifier testing. Sakana is in a position to change that — they have the orchestrator, the model pool, the benchmarks, and the engineering bench. The planted-fault eval would land in a single appendix. &lt;strong&gt;What it would tell us is whether the third opinion is a verifier or a vote.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Companion piece: &lt;a href="https://dev.to/jugeni/a-quorum-costume-why-agent-verification-needs-fault-injection-kbh"&gt;a-quorum-costume-why-agent-verification-needs-fault-injection&lt;/a&gt; — the same gap one floor below, from operator stack instead of production orchestration.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llmops</category>
      <category>evaluation</category>
    </item>
    <item>
      <title>I built a football bot that doesn't watch football. It's #2 in our World Cup league.</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Tue, 23 Jun 2026 19:17:46 +0000</pubDate>
      <link>https://dev.to/jugeni/i-built-a-football-bot-that-doesnt-watch-football-its-2-in-our-world-cup-league-2b18</link>
      <guid>https://dev.to/jugeni/i-built-a-football-bot-that-doesnt-watch-football-its-2-in-our-world-cup-league-2b18</guid>
      <description>&lt;p&gt;The bot is sitting in second place out of fourteen. Three points behind the leader.&lt;/p&gt;

&lt;p&gt;The thirteen humans in this league watch a lot more football than I do, and the leader watches more football than most of them. The bot has never seen a match.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;A friends-only prediction league, World Cup 2026, thirteen humans and one bot. The league is private, so I won't link it. The bot's name in the standings is "mike," same as mine, which the others find funnier than I do.&lt;/p&gt;

&lt;p&gt;I wrote two files. &lt;code&gt;client.py&lt;/code&gt; does session-cookie auth against the league's API and exposes &lt;code&gt;matches()&lt;/code&gt;, &lt;code&gt;me()&lt;/code&gt;, and &lt;code&gt;put_bet(match_id, home, away)&lt;/code&gt;. &lt;code&gt;revise.py&lt;/code&gt; runs from cron every fifteen minutes, looks at upcoming matches in a window 90 to 200 minutes before kickoff, asks Claude for a verdict, and writes the bet if anything has changed. Idempotent state guard — same match won't get re-revised in the same pre-window. Per-match JSON record of every decision, with reasoning. The whole thing is under 250 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three rules
&lt;/h2&gt;

&lt;p&gt;The prompt to Claude is structured and small. It asks for: home goals, away goals, confidence level, and a one-sentence reason that has to cite exactly one of three rules.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Squad-value ratio.&lt;/strong&gt; Estimated market value of each squad. If one side is clearly more expensive than the other, that side scores more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Class gap.&lt;/strong&gt; Is one of these teams a debutant or weak federation member, and the other a top-eight nation by recent results? If yes, the modal score gets pushed harder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pace mismatch.&lt;/strong&gt; Does one side's attack-speed style obviously punish the other side's defensive shape?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the whole rulebook. No "team chemistry." No "the manager's been under pressure." No "momentum from the last group game." No "this is the kind of fixture Brazil tends to drop points in." Three crude structural proxies for &lt;em&gt;is one of these teams obviously the better one&lt;/em&gt;, and a confidence level that determines how aggressive the modal scoreline gets.&lt;/p&gt;

&lt;h2&gt;
  
  
  The standings
&lt;/h2&gt;

&lt;p&gt;Full table as of this morning. Other players anonymized (single letters), bot's row in bold:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Place&lt;/th&gt;
&lt;th&gt;Player&lt;/th&gt;
&lt;th&gt;Pts&lt;/th&gt;
&lt;th&gt;Exact&lt;/th&gt;
&lt;th&gt;Diff&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Bets&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;71&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;72&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;bot mike&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;68&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;28&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;44&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;72&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;63&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;F&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;G&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;H&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;69&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;J&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;63&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;K&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;L&lt;/td&gt;
&lt;td&gt;37&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The top of the table looks like this in prose: player A is at 71 points with six exact scores and a prediction in every single match of the tournament. From past chat in our group, this person watches football constantly — clubs across three leagues, knows squad rotations, follows transfer news. A serious follower. The bot is three points behind, with three exact scores. Player B at #3, also a serious follower, is one point further back.&lt;/p&gt;

&lt;p&gt;The bot is sitting one row below a real follower of the game. Not by being smarter. Not by knowing football. By being a small structured system run by someone who, on a normal day, has to be reminded which group Senegal is in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is the part that interests me
&lt;/h2&gt;

&lt;p&gt;Most of the people in this league are serious football followers. They watch matches. They form intuitions. They have opinions about which team underperforms its squad value, which side fades in second halves, which manager makes the wrong substitution against teams with fast wingers. That knowledge is real, and it isn't easily replaced.&lt;/p&gt;

&lt;p&gt;And yet a 250-line script with three rules and a cron job is sitting above twelve of them.&lt;/p&gt;

&lt;p&gt;The bot doesn't beat the leader. It doesn't outperform actual football intuition at the top of the table. What it does is beat almost everyone else, despite having none of the inputs they have. That gap — between domain-rich intuition and a small disciplined system in a fresh domain — is the thing I keep noticing in my other work, and I didn't expect to see it lit up this cleanly in a prediction league.&lt;/p&gt;

&lt;p&gt;The discipline isn't football-specific. It's: define a small structured prompt, run it on cron, write a per-match record, let the model worker do the worker job, and let the structure around the model decide &lt;em&gt;when to act and when to keep the previous bet&lt;/em&gt;. That structure is doing more of the work than the model is.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few honest caveats
&lt;/h2&gt;

&lt;p&gt;The bot probably doesn't stay at #2 through the whole tournament. The knockout rounds get messier. Squad-value ratios get less reliable in tournament football because the variance is high, and three crude rules will miss the kind of nuance the top human catches in tight quarter-finals. The bot's lead over the rest of the league is real today. Whether it holds is a separate question.&lt;/p&gt;

&lt;p&gt;Also: the bot is not clever in the prediction itself. Claude isn't running a Bayesian model under the hood. It's pattern-matching on a small structured prompt with three rules. The cleverness, such as it is, is in the architecture around the model — the cron cadence, the state guard, the structured rule set, the per-match JSON log. The model is the worker. The structure decides when the worker is allowed to ship.&lt;/p&gt;

&lt;p&gt;That distinction is most of the post. The bot isn't beating football fans because the model is smart. It's beating most of them because the system around the model is small, structured, and consistent — and most casual prediction isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Footer
&lt;/h2&gt;

&lt;p&gt;If this sounds like the &lt;a href="https://dev.to/jugeni/vibe-coding-is-not-a-level-its-an-axis-4lc9"&gt;vibe-coding-is-not-a-level&lt;/a&gt; framing — it is. In a fresh domain, a small disciplined system can get surprisingly close to domain intuition — and sometimes beat loosely applied intuition outright. I was writing about this in software last week. I'm writing about it in football this week. The shape doesn't care which domain it lives in.&lt;/p&gt;

&lt;p&gt;The bot's predictions will keep landing through the group stage. The standings will move. I'll write the follow-up when they do.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llmops</category>
      <category>showdev</category>
    </item>
    <item>
      <title>A quorum costume: why agent verification needs fault injection</title>
      <dc:creator>Mike Czerwinski</dc:creator>
      <pubDate>Tue, 23 Jun 2026 14:13:09 +0000</pubDate>
      <link>https://dev.to/jugeni/a-quorum-costume-why-agent-verification-needs-fault-injection-kbh</link>
      <guid>https://dev.to/jugeni/a-quorum-costume-why-agent-verification-needs-fault-injection-kbh</guid>
      <description>&lt;p&gt;Yesterday I watched my AI partner miss the same source-of-truth problem three times in a row, in three different forms, across three different review surfaces.&lt;/p&gt;

&lt;p&gt;It wrote a draft in the wrong voice. A reviewer-session of the same model read it twice and rated it progressively higher. A meta-receipt at the end of the post miscounted the number of review rounds — fact drift inside a paragraph about fact drift. I caught all three only because I was sitting outside the loop with access the reviewers didn't have.&lt;/p&gt;

&lt;p&gt;I wrote about the failures themselves the same evening. This is the part underneath them.&lt;/p&gt;

&lt;p&gt;Each of those catches has the same structure as a much bigger class of failure across the agent stack right now: a verification surface that is supposed to be independent of the thing it verifies, but isn't. The check shares lineage with the claim. The reviewer reads from the same source as the writer. The agreement loop walks the same path the disagreement was supposed to fall out of.&lt;/p&gt;

&lt;p&gt;That's not a flaw in any particular framework. It's the assumption nobody verified before they shipped the framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  The diagnosis, one floor up
&lt;/h2&gt;

&lt;p&gt;Almost every verification scheme in the current agent stack quietly bets on independence between paths.&lt;/p&gt;

&lt;p&gt;Multi-agent voting bets on it. Cross-layer coherence checks bet on it. Quorum reads, consistency loops, maker/checker patterns, two-pass LLM reviews, ensemble-of-prompts setups — every one of them ships with the premise that the views being combined are in some useful sense disjoint. Disagreements are supposed to surface real divergence. Agreement is supposed to mean the real signal cleared a structural test.&lt;/p&gt;

&lt;p&gt;Most of the ones I see do not make the independence assumption observable.&lt;/p&gt;

&lt;p&gt;Self-Correcting Systems named it cleanly in a commissioning thread for this post: an unverified independence assumption is indistinguishable from a single point of failure wearing a quorum costume. That line does most of the work of this post. Until you've checked that the paths actually disagree on the thing they're supposed to disagree on, you don't have N views. You might have one view in N hats and no way to tell.&lt;/p&gt;

&lt;p&gt;The costume is the part that fools you. The vote returned unanimous. The reviewers agreed. The cross-check passed. From inside the system everything looks like the verification did its job. From outside — where someone can see that all the paths share an upstream — it's one signal repeated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disagreement rate isn't the test
&lt;/h2&gt;

&lt;p&gt;The reflex move when this gets named is: fine, measure disagreement rate as a smoke test. If the views never disagree, they're not independent.&lt;/p&gt;

&lt;p&gt;This is a useful check, and it isn't the test.&lt;/p&gt;

&lt;p&gt;Two paths can disagree on phrasing and agree on the same wrong fact. They can disagree on confidence and converge on the same hallucination. They can disagree on tone and share the same upstream retrieval that handed both of them the bad context. The agreement that matters is the one on the thing that actually carries the load — and that's exactly the dimension where shared lineage is hardest to see, because the words on the surface are different.&lt;/p&gt;

&lt;p&gt;Disagreement on noise while sharing the upstream that actually matters is the worst possible failure mode for an independence claim. It looks healthy. It produces nicely varied outputs. It survives smoke tests. And it fails in the same direction every time the upstream lies.&lt;/p&gt;

&lt;p&gt;The real test isn't whether the views disagree on their own. It's whether you can make them disagree by perturbing the system. That's a different shape of measurement entirely.&lt;/p&gt;

&lt;p&gt;A compact diagnostic to keep in front of you:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Shared upstream&lt;/th&gt;
&lt;th&gt;Injected fault&lt;/th&gt;
&lt;th&gt;Expected divergence&lt;/th&gt;
&lt;th&gt;What "coupling detected" looks like&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Retriever-A vs Retriever-B&lt;/td&gt;
&lt;td&gt;embedding model M&lt;/td&gt;
&lt;td&gt;Plant a contradictory fact through one path's index only&lt;/td&gt;
&lt;td&gt;A returns corrupted, B returns clean&lt;/td&gt;
&lt;td&gt;Both return corrupted (same embedding pulls the bad cell on either side)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maker vs Checker&lt;/td&gt;
&lt;td&gt;rule cache R&lt;/td&gt;
&lt;td&gt;Mutate the rule offline so the correct verdict changes&lt;/td&gt;
&lt;td&gt;Maker uses mutated R, Checker flags the divergence&lt;/td&gt;
&lt;td&gt;Both pass (Checker reads cached pre-mutation R, never re-fetches)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telemetry vs anteriority check&lt;/td&gt;
&lt;td&gt;served-model record&lt;/td&gt;
&lt;td&gt;Plant the wrong &lt;code&gt;response.model&lt;/code&gt; value&lt;/td&gt;
&lt;td&gt;Anteriority check reads independently-controlled record and flags mismatch&lt;/td&gt;
&lt;td&gt;Anteriority check passes (it reads the same record the telemetry wrote)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The columns are the operational shape. Without the last column, you can't tell whether the verification was doing work or sitting green because nobody perturbed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the field has practical methods for this
&lt;/h2&gt;

&lt;p&gt;Distributed systems hit this problem about twenty years ago and developed practical methods for testing specific failure assumptions. The methods don't prove independence in the general case — they expose dependence when it exists.&lt;/p&gt;

&lt;p&gt;Jepsen runs partition tests against databases that claim consistency, and the only way to find out whether the claim survives a network failure is to cause the network failure. Chaos Monkey kills production instances on purpose. Game-day exercises shut down regions and watch whether the system that claims regional redundancy actually has it. Property-based testing throws structured-random inputs at code that claims to be correct under all inputs. The pattern repeats: you don't measure resilience by watching the system run well. You measure it by inducing the failure mode the claim was supposed to survive — within the safety boundary the operator has authorized.&lt;/p&gt;

&lt;p&gt;Agent and memory architectures didn't inherit this discipline. The reason isn't technical — the tooling is straightforward. The reason is cultural. Distributed systems treat state as something you have to perturb to trust. Agent stacks treat state as something you write to and read from and trust by default. The whole design vocabulary is built around storing, retrieving, embedding, and ranking — none of which has a perturbation primitive in it.&lt;/p&gt;

&lt;p&gt;That's the gap. Not "we don't know how to verify independence." We do, in the specific cases we test for. The gap is that the harness is still rarely treated as the price of admission.&lt;/p&gt;

&lt;h2&gt;
  
  
  What fault injection actually means here
&lt;/h2&gt;

&lt;p&gt;Strip the term down: trace the lineage of a claim, induce a known bad state in one of the paths that produced it within a bounded blast radius, and confirm that the "independent" check catches the divergence — or quietly absorbs it.&lt;/p&gt;

&lt;p&gt;Three concrete moves on the kinds of stacks I'm running:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inject a synthetic-bad memory entry.&lt;/strong&gt; Pick a fact in the agent's semantic store. Plant a contradictory version through one retrieval path's index but not the other, in a sandbox or staging environment. Run the agreement loop. The injected fault is the planted contradiction; the observable assertion is whether the two paths return different values; the negative control is the same query run before the injection, returning consistent values from both paths; the condition that constitutes coupling is unanimous agreement on the corrupted value plus matching provenance IDs across both paths. If the loop returns unanimous, the loop wasn't reading two paths — it was reading one path twice with different formatting, and the provenance trail proves it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mutate a router rule offline.&lt;/strong&gt; Take a rule the agent applies through one decision path. State explicitly what the maker/checker pattern is supposed to detect — for example, that the checker should flag any verdict computed from rule version N+1 when the policy still records version N. Mutate the rule in the offline copy so a known request that previously routed to verdict X now routes to verdict Y. Re-run the maker/checker on that specific known request. The expected divergence is the checker flagging mismatch between policy-version-recorded and policy-version-applied. If both maker and checker pass, they were sharing the cached policy and the second role was a presentation layer, not a check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plant the wrong &lt;code&gt;response.model&lt;/code&gt; in telemetry.&lt;/strong&gt; Define your terms first: the anteriority check is the diagnostic that compares the served-model identifier in telemetry against the served-model intent-spec — a build-time manifest or external provenance store that names which model should have served which request type. The independently-controlled record is the intent-spec, authored at build time and stored where the runtime can't rewrite it. Log an answer with a deliberately wrong served-model identifier. The expected outcome is the anteriority check reading the intent-spec, comparing it against the planted telemetry, and flagging mismatch. If the check passes, the check was reading the same record the writer wrote — no anchor outside the writer's reach.&lt;/p&gt;

&lt;p&gt;In all three, the value isn't the specific bug you find. It's the binary answer to a question the system couldn't answer about itself otherwise: does the second path actually catch the first, or has the costume been fooling everyone — including the team that wrote both halves?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The operational split underneath.&lt;/strong&gt; Raffaele Zarrelli, designing slow-loop memory updates at cowork-os, surfaced the question that turns this from a one-time test into a sustained discipline: who actually authors the verifier? The shape that holds up: the operator authors the verifier choice at lock time — picks the anchor, names the expected resolution, sets the cadence — because picking the right anchor is a judgment call that doesn't scale into the mechanism. The diagnostic firing is mechanical: a cron walks all locked entries on cadence, runs their verifiers against current reality, flags any whose resolution diverged or whose verifier itself failed to run. Operator picks the anchor; mechanism fires the check. Same shape as the apply/advisory split — operator authorizes the binding, mechanism surfaces the drift without authority to flip status.&lt;/p&gt;

&lt;p&gt;One constraint goes with this: the verifier itself has to target something the writing session can't reach. Operator picks the anchor at lock, but if the anchor is a grep against the operator's own filesystem in the same session that wrote the decision, the whole thing collapses into wording-check one floor up — same disease, longer chain. The smallest useful version: verifier targets must be externally authored. CI run signed by a service the operator didn't author. Commit by a counterparty. Vendor receipt with an audit trail. World-state record outside the operator's write path. Anything the lock session could rewrite from inside itself isn't a verifier; it's a label.&lt;/p&gt;

&lt;p&gt;A five-step working checklist, distilled:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Map the lineage&lt;/strong&gt; of the claim — who wrote it, what context flowed in, which upstream produced what.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select one boundary to perturb&lt;/strong&gt; — pick a path you can perturb without breaking production; default to synthetic data, sandbox, or staging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inject a controlled fault&lt;/strong&gt; — known-bad state, single path, bounded blast radius, rollback ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observe the alternate path&lt;/strong&gt; — does the supposedly-independent check catch the divergence or absorb it silently? Capture provenance from both paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record pass criteria&lt;/strong&gt; — what was injected, what fired, what didn't, what would have constituted a clean pass.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The same logic generalizes. Pick a verification claim. Pick a single path. Perturb the path within a safe boundary. Watch the verification. If the verification doesn't flinch when the input lies, the verification was never a verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Independence decays
&lt;/h2&gt;

&lt;p&gt;If you stop here you've built the harness once and you're done. That's the next assumption to drop.&lt;/p&gt;

&lt;p&gt;Independence is not a property you establish. It's a property you re-verify.&lt;/p&gt;

&lt;p&gt;The reason is small and brutal: you can wire up two paths today, prove they're disjoint with a clean fault-injection pass, ship the result, and have somebody refactor a shared cache into the middle of both paths next month. The vote still returns. The agreement loop still fires. The smoke test still looks healthy. And your June fault-injection pass certifies a system that doesn't exist in August anymore. You measured an independence that has since collapsed and nothing in the loop tells you it collapsed, because every visible signal is downstream of the shared cache.&lt;/p&gt;

&lt;p&gt;This is the same disease as integrity-is-not-anteriority, applied to the orthogonal axis. Integrity at a moment is not a verifiable history. Independence at a moment is not sustained disjoint paths. Both are properties of time, not properties of state.&lt;/p&gt;

&lt;p&gt;The operating model worth running alongside this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Triggers that should fire a re-verification:&lt;/strong&gt; a new shared cache between two paths, a retrieval source change that lets the same upstream feed both views, a router change that overlaps previously-disjoint paths, a policy store change that moves the rule deciding "which path runs," a telemetry schema change that alters what two checks compare against, a model family change that introduces shared training lineage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cadence:&lt;/strong&gt; at least monthly, plus per-trigger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure owner:&lt;/strong&gt; named per system. An alarm that fires without an owner is a checkbox with no consequence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actionable policy sentence:&lt;/strong&gt; rerun the relevant injection test whenever a shared cache, retrieval source, router, policy store, telemetry schema, or model family changes — or monthly, whichever comes first.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's a second decay nobody mentions. The harness itself rots.&lt;/p&gt;

&lt;p&gt;If the fault-injection step exists but nobody ever runs it, or nobody ever shoves a known-bad state through it that should trip it, the harness becomes a checkbox. Green because nobody's measuring. Green because the injector has bit-rot in a dependency since the last real test. Green because someone refactored the test fixtures and the perturbation now silently no-ops. The harness is one more thing in the system that has to be perturbed periodically or it stops being a measurement and starts being decor.&lt;/p&gt;

&lt;p&gt;Treat the harness like the model. Assume it drifts. Re-perturb, don't only re-check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signals from adjacent work
&lt;/h2&gt;

&lt;p&gt;This isn't only a private failure mode. The same shape is showing up in adjacent work this month.&lt;/p&gt;

&lt;p&gt;In agent security, deterministic permission gates move tool-call decisions out of the model's discretion. In memory systems, supersede edges and provenance make it possible to ask what replaced what and why. In larger agent harnesses, the infra layer is decomposing into sandboxes, memory, skills, sub-agents, and gateways.&lt;/p&gt;

&lt;p&gt;Those are useful primitives. But none of them remove the independence question. A gate can still share lineage with the claim it gates. A memory substrate can still retrieve twelve agreeing episodes through the same broken path. A harness can still ship impressive infrastructure while leaving the verification layer above it untested. The infra layer is closing fast. The verification layer above it still feels under-built: not because nobody has pieces of it, but because independence is rarely made measurable as a first-class property.&lt;/p&gt;

&lt;p&gt;The pattern is no longer just my thesis. It is showing up across enough adjacent work that I would treat it as an emerging baseline candidate — not because the field has agreed on it, but because the same constraint keeps forcing the same shape. The next baseline is not "more checks." It is checks whose independence has been perturbed, measured, and re-verified after the system changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;The line from the post I wrote yesterday holds at this level too: two sessions of the same model do not constitute two views; they constitute one view, twice.&lt;/p&gt;

&lt;p&gt;The version one floor up: two paths that share an upstream do not constitute two views; they constitute one view, twice, in different fonts.&lt;/p&gt;

&lt;p&gt;Independence is a design-time-vs-runtime distinction. You design for it by separating the paths a verification touches from the paths the thing-being-verified touches. You verify it at runtime by inducing a failure in one path and watching whether the other path notices. You re-verify it next month because the system you measured in June isn't the system running in August.&lt;/p&gt;

&lt;p&gt;Everything else — the agreement rate, the consistency loop, the quorum result, the cross-check that came back unanimous — is internal coherence wearing the costume of independent verification. Formal lineage analysis, provenance controls, and architectural isolation can provide partial evidence: they certify what the system was at construction. They don't certify what it currently is.&lt;/p&gt;

&lt;p&gt;The strongest operational measurement proposed here is the one that perturbs the system and watches what flinches. Anything the system could rewrite from inside itself isn't a verifier; it's a label.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Credits &amp;amp; references&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The "single point of failure wearing a quorum costume" framing and the independence-decay dimension came from Self-Correcting Systems in a public commissioning thread under &lt;a href="https://dev.to/jugeni/you-cant-be-your-own-second-view-four-ai-failures-from-one-day-of-operator-work-2e5o"&gt;&lt;em&gt;You can't be your own second view&lt;/em&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The verifier-shape architectural co-design (operator-picks-anchor + mechanism-fires-cron + verifier-targets-must-be-externally-authored) and the time-as-different-class framing came from Raffaele Zarrelli's work on &lt;a href="https://github.com/sarracin0/cowork-os" rel="noopener noreferrer"&gt;cowork-os&lt;/a&gt; and a cross-thread exchange this week.&lt;/li&gt;
&lt;li&gt;The CrewAI permit/defer/deny architecture with hash-chained decision logging and the analyzer-suggests-diff-operator-applies pattern is Brian Hall's work at Faramesh Labs (&lt;a href="https://dev.to/brianrhall"&gt;&lt;em&gt;Put a hard stop in front of your CrewAI crew's tool calls&lt;/em&gt;&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The push-memory substrate primitives (supersede edges, computed-not-stored confidence, off-test for shadowed memory) come from Todd Hendricks's five-part &lt;em&gt;Agentic Memory Study&lt;/em&gt; and the &lt;a href="https://github.com/H-XX-D/recall-memory-substrate" rel="noopener noreferrer"&gt;Recall&lt;/a&gt; substrate.&lt;/li&gt;
&lt;li&gt;The industry-scale infra receipt is ByteDance's &lt;a href="https://github.com/bytedance/deer-flow" rel="noopener noreferrer"&gt;DeerFlow 2.0&lt;/a&gt; — open-source SuperAgent harness ground-up rewrite (approximately 73,000 GitHub stars as of June 23, 2026, MIT) shipping sandboxes + memory + sub-agents + skills + message gateway as one stack at the infra layer.&lt;/li&gt;
&lt;li&gt;Companion posts: &lt;a href="https://dev.to/jugeni/salience-is-not-carry-value-notes-from-a-running-session-memory-pipeline-4dda"&gt;&lt;em&gt;Salience is not carry value&lt;/em&gt;&lt;/a&gt; on selection-time policy in memory pipelines, and &lt;a href="https://dev.to/jugeni/you-cant-be-your-own-second-view-four-ai-failures-from-one-day-of-operator-work-2e5o"&gt;&lt;em&gt;You can't be your own second view&lt;/em&gt;&lt;/a&gt; on the single-agent case of the same failure.&lt;/li&gt;
&lt;li&gt;Background: Anthropic Economic Research, &lt;a href="https://www.anthropic.com/research/claude-code-expertise" rel="noopener noreferrer"&gt;&lt;em&gt;Agentic coding and persistent returns to expertise&lt;/em&gt;&lt;/a&gt; (Hitzig et al., June 2026), independent empirical anchor for the operator-discipline axis underneath this whole arc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Additional peer references — NOVA Network on synthetic-quorum and out-of-band alarms; Christopher Maher (LLMKube) on bite-check; Vishal Keerthan and Elliott Schmechel on routing-embedding-as-input-side-drift-catch and constraints-driven convergence; Shudipto Trafder on the CoALA seven-memory-types taxonomy; Theo Valmis on engineering-with-AI as designing where the model is allowed to be wrong; jugeni's audit log integration contract at &lt;a href="https://github.com/jugeni/jugeni-contracts" rel="noopener noreferrer"&gt;github.com/jugeni/jugeni-contracts&lt;/a&gt; — will appear in a follow-up post that walks each thread individually.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llmops</category>
      <category>agentmemory</category>
    </item>
  </channel>
</rss>
