<?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: Viscount Sparrow</title>
    <description>The latest articles on DEV Community by Viscount Sparrow (@viscount_sparrow_671be893).</description>
    <link>https://dev.to/viscount_sparrow_671be893</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3968159%2F081b1e02-840a-42e0-bc94-c99c5ac89fc9.png</url>
      <title>DEV Community: Viscount Sparrow</title>
      <link>https://dev.to/viscount_sparrow_671be893</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viscount_sparrow_671be893"/>
    <language>en</language>
    <item>
      <title>Code that looks right and lies: a field guide to intent↔code drift</title>
      <dc:creator>Viscount Sparrow</dc:creator>
      <pubDate>Thu, 04 Jun 2026 11:08:48 +0000</pubDate>
      <link>https://dev.to/viscount_sparrow_671be893/code-that-looks-right-and-lies-a-field-guide-to-intent-code-drift-592l</link>
      <guid>https://dev.to/viscount_sparrow_671be893/code-that-looks-right-and-lies-a-field-guide-to-intent-code-drift-592l</guid>
      <description>&lt;p&gt;AI agents now write enormous amounts of code, and it usually looks right. It compiles, it passes the tests, it reads cleanly in review. But "looks right" and "does what it said it would" are different things — and the gap between them is where the real bugs hide now.&lt;/p&gt;

&lt;p&gt;I keep seeing the same failure mode: a pull request claims one thing, and the diff quietly does another. The reviewer reads the claim, confirms the claim is present, and sails right past the part nobody mentioned. At PR volume — especially with agents generating the code — humans simply can't audit every change for&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Silent scope — the change does more than it claims&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most dangerous one, because the extra behavior hides behind a true, narrow description.&lt;/p&gt;

&lt;p&gt;import { logger } from "../log";&lt;br&gt;
  -const SESSION_TTL = 30 * 60;        // 30 minutes&lt;br&gt;
  +const SESSION_TTL = 24 * 60 * 60;   // 24 hours&lt;br&gt;
   export function createSession(user) {&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; logger.info("creating session for", user.id);
 return { user, ttl: SESSION_TTL };
}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;▎ PR says: "Add debug logging to session creation. No behavior changes."&lt;/p&gt;

&lt;p&gt;The logging is real — and that truth is the camouflage. The 48× session-lifetime change is the actual risk, and a reviewer skimming for "logging" never sees it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Unbacked claim — the description promises what the code doesn't deliver&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;// PR: "Adds rate limiting (5 req/min) to the login route."&lt;br&gt;
   router.post("/login", async (req, res) =&amp;gt; {&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; logger.info("login attempt", req.ip);
 const user = await authenticate(req.body);
 return res.json({ token: sign(user) });
});&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The body advertises rate limiting; the diff adds a log line and nothing that counts or rejects requests. The title set an expectation strong enough that your brain auto-filled the missing implementation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Doc drift — code and its referenced doc now contradict each other&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;-// Spec (CLEANUP.md): "expireStaleData runs once daily at 04:00 UTC."&lt;br&gt;
  -exports.expireStaleData = schedule("every 24 hours").onRun(...);&lt;br&gt;
  +exports.expireStaleData = schedule("every 1 hours").onRun(...);&lt;/p&gt;

&lt;p&gt;Nobody updated the doc. Six months later someone reasons about load using "daily" and is wrong by 24×. Your most trusted reference becomes confidently wrong.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Missing impl — a stated requirement has no code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;// Spec: "Players get 3 free guesses; extras are paid (max +2)."&lt;br&gt;
  -const FREE_GUESSES = 3;&lt;br&gt;
  +const FREE_GUESSES = 1;            // paid extras: TODO&lt;/p&gt;

&lt;p&gt;"Behind the spec" is fine if everyone knows. Drift is when only the code knows — and the spec keeps overstating what ships.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Intent mismatch — the code does something different from the claim&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;// Design: "All message writes go through the server trigger."&lt;br&gt;
   match /matches/{id}/messages/{msgId} {&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; allow create: if false;          // server-only&lt;/li&gt;
&lt;li&gt; allow create: if isMember(id);   // client writes directly
}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The feature still "works" — through a different door than the one the design built. The mismatch only bites later: a missing notification, an unmoderated message, a broken rollup.&lt;/p&gt;

&lt;p&gt;Why this is hard to catch by hand&lt;/p&gt;

&lt;p&gt;Every one of these passes CI and looks clean. The signal isn't in the code's quality — it's in the distance between the code and its stated intent. That's a comparison, and it's exactly the kind humans stop doing carefully at scale.&lt;/p&gt;

&lt;p&gt;So I built a small open-source tool for it: Verdict reads a PR's declared intent (issue / description / linked spec) and the actual diff, and flags only these fidelity gaps — evidence-backed, or nothing. Not a style linter, not a general reviewer. It runs as a GitHub Action and a CLI, and it's model-agnostic&lt;br&gt;
  (OpenAI-compatible or Anthropic).&lt;/p&gt;

&lt;p&gt;The first thing I did was run it on its own codebase. It found 16 real issues I then fixed — including a way an attacker's PR text could try to talk the judge into passing. Dogfooding a verification tool is the only honest way to ship one.&lt;/p&gt;

&lt;p&gt;It's early (v0). If the "claim vs code" gap is something you've felt, I'd genuinely like your eyes on it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/verdict-ci/verdict" rel="noopener noreferrer"&gt;https://github.com/verdict-ci/verdict&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm i -g verdict-ci then git diff main... | verdict --intent "what you meant to do"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What drift patterns have bitten you that aren't on this list? That's the part I most want to hear.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>github</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
