<?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: Wageesha Tripathi</title>
    <description>The latest articles on DEV Community by Wageesha Tripathi (@wst2002rk).</description>
    <link>https://dev.to/wst2002rk</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%2F4200986%2F8d1dd177-3969-434b-a5e7-a0a1e3f952d0.jpg</url>
      <title>DEV Community: Wageesha Tripathi</title>
      <link>https://dev.to/wst2002rk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wst2002rk"/>
    <language>en</language>
    <item>
      <title>I asked for one more way AI code is "almost right". You gave me seven.</title>
      <dc:creator>Wageesha Tripathi</dc:creator>
      <pubDate>Thu, 12 Nov 2026 06:29:20 +0000</pubDate>
      <link>https://dev.to/wst2002rk/i-asked-for-one-more-way-ai-code-is-almost-right-you-gave-me-seven-3ien</link>
      <guid>https://dev.to/wst2002rk/i-asked-for-one-more-way-ai-code-is-almost-right-you-gave-me-seven-3ien</guid>
      <description>&lt;p&gt;Last week I wrote about &lt;a href="https://dev.to/wst2002rk/your-ais-code-is-almost-right-here-are-7-ways-it-fools-you-and-the-30-second-check-for-each-4i93"&gt;7 ways AI code is "almost right"&lt;/a&gt;. At the end I asked you for an 8th way and promised to share the best answers here, with credit.&lt;/p&gt;

&lt;p&gt;I asked for one. You gave me seven: five brand new ones, and two that make checks from my list sharper. Mudassir also shared a simple rule from his team, it's near the end. Honestly, a few of your replies taught me more than my own post did. Thank you to everyone who took the time to write them out, some of these clearly came from a bad day in production.&lt;/p&gt;

&lt;p&gt;Quick confession before we start. The cover for that post came from an image generator, and on the first try it dropped one word from my headline. The picture looked great. The sentence was wrong. I caught it just before saving. Kind of embarrassing, considering what the post was about.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Right shape, wrong value
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/member_957b667c/comment/3klai"&gt;Maxwell's comment&lt;/a&gt; is the one that worries me most. No exception, nothing to catch, the field is filled in. It's just not what the source said. In his words, "a parser can read annual as monthly across a whole layout and never once fail."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check (his):&lt;/strong&gt; pick 5 rows at random and compare them with the source by hand. Random matters. If you only check the rows that already looked odd, you catch nothing.&lt;/p&gt;

&lt;p&gt;I'd add two things: check the labels and units in those rows too, and if the source has a total you can trust (a column sum, a row count), compare it. A matching total doesn't prove every field is right, but a wrong conversion usually shows up there first.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. You asked for one line. It tidied three files.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/stackmasteraliza/comment/3k9nc"&gt;Aliza Ali&lt;/a&gt; calls this silent scope creep. You ask for a one-line fix, and the diff also renames a variable, "cleans up" an import and touches files you never mentioned. On their own, none of those changes looks worth worrying about. Together they change a lot more than you asked for.&lt;/p&gt;

&lt;p&gt;Her follow-up made a point I hadn't thought about: auto-accept makes this much more likely, but step-by-step review doesn't fully save you either, because each edit looks reasonable in isolation. The final diff is the only view that shows the whole footprint at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; run &lt;code&gt;git diff --stat&lt;/code&gt; before reading a single line (or &lt;code&gt;git diff --stat main...HEAD&lt;/code&gt; if the agent already committed). More files isn't automatically bad, since a real fix can need its test and a type too. But ask about every file you didn't expect before reviewing anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. State that drifts
&lt;/h2&gt;

&lt;p&gt;This one is harder to spot, because the code reads clean. &lt;a href="https://dev.to/khalisollis/comment/3k9oa"&gt;Khali Sollis&lt;/a&gt; described a custom hook or async routine that passes the first render test but quietly misses a reactive dependency, or closes over stale state. It "works fine during a quick manual check, but drifts out of sync the second real users start interacting with the UI sequentially."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; don't test it once after a fresh load. Change the state a few times in a row, and trigger anything that runs later (timers, async callbacks). Also look for a newly added &lt;code&gt;eslint-disable&lt;/code&gt; for &lt;code&gt;react-hooks/exhaustive-deps&lt;/code&gt; in the diff. That rule catches many of these, and silencing it is the quickest way to make the warning go away.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. The test that would have caught it was mocked away
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/mp3sss31/comment/3k60o"&gt;mp3sss&lt;/a&gt; sees this in Electron work. An AI-written IPC handler looks correct but never validates what the renderer sends, and the integration test that should catch that is mocked. Same story around auto-update and crash reporting: the happy path is easy to generate, and the failure path (network down, partial download, a stale crash dump) is exactly what gets skipped.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/mudassirworks/comment/3keoo"&gt;Mudassir Khan&lt;/a&gt; hit the same wall from another side: a &lt;code&gt;catch&lt;/code&gt; that returns an empty array passes every test, because the same agent wrote the tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; for each AI change, force one failure on purpose. Cut the network, send a bad payload, break the dependency, and make sure you get an error instead of a quiet empty result. As mp3sss put it, "pairing each AI change with a forced failure-path test has saved us more than the happy-path tests did."&lt;/p&gt;

&lt;h2&gt;
  
  
  12. The flaky test that got a longer timeout
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/maxbuildsdev/comment/3k37a"&gt;Max Kaya&lt;/a&gt; added this one to the test checks from #2. Besides &lt;code&gt;toBe&lt;/code&gt; quietly turning into &lt;code&gt;toBeTruthy&lt;/code&gt;, watch for a timeout extended "to fix flakiness". In his words, it "usually means the test now passes by construction."&lt;/p&gt;

&lt;p&gt;Sometimes the old timeout really was too tight for CI. Often, though, the slow call or the race is still there, and you've just stopped hearing about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; search the diff for bigger timeout numbers and new retries (&lt;code&gt;retries&lt;/code&gt;, &lt;code&gt;jest.retryTimes&lt;/code&gt;, &lt;code&gt;--retries&lt;/code&gt;). Each one should point to a timing problem someone actually understands.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. A real package, but far too much of it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/friga/comment/3kc3p"&gt;Artur Pokładek&lt;/a&gt; called this a cousin of #3. The package exists and is popular, it just pulls in a pile of dependencies for something that was fifteen lines of code. He accepted one from an agent without looking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check (his):&lt;/strong&gt; &lt;code&gt;git diff --stat&lt;/code&gt; on the lockfile. If it grew by hundreds of lines for a small feature, ask why. A big lockfile diff can have boring causes too, so treat it as a reason to look, not as proof.&lt;/p&gt;

&lt;p&gt;I asked him what he does then, and his answer is a better rule than anything I had. A small helper, he writes himself and tests. Dates, parsing and crypto stay with a well-known library, because there his own fifteen lines would be the bug. The small lookalike package is the option he trusts least.&lt;/p&gt;

&lt;h2&gt;
  
  
  14. It passes everything, and never ships
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/baigorria/comment/3k2ii"&gt;Guillermo Baigorria&lt;/a&gt; had this happen the day before he commented. The AI fixed a bug with a new patch folder, and every test passed on his machine. But the deploy script packs a fixed list of folders, and the new one wasn't on it. No test could see that, because tests run where the file exists.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/paullovelace/comment/3k3f4"&gt;Paul Lovelace&lt;/a&gt; called it the gap between where tests run and what actually ships, and said this is the check he'd steal first.&lt;/p&gt;

&lt;p&gt;The list is hard-coded on purpose, by the way. A fixed list is what keeps a stray &lt;code&gt;.env&lt;/code&gt; from shipping. So Guillermo's team checks the built package instead of the script, flags new files, and a person decides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check (his):&lt;/strong&gt; list the files the change added, then look for each one in what you ship.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff --name-status main &lt;span class="o"&gt;|&lt;/span&gt; grep &lt;span class="s1"&gt;'^A'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that with your Dockerfile &lt;code&gt;COPY&lt;/code&gt; lines or the &lt;code&gt;files&lt;/code&gt; list in your &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A rule worth copying
&lt;/h2&gt;

&lt;p&gt;Mudassir also sent a defence against #2 from last time. His point: when the test file changed in the same diff, a green run tells you very little. It shows the new test passes, not that the old behaviour is still checked. So his team's rule is that any diff touching a test file needs a one-line reason in the PR, and their review bot fails a test that got skipped or loosened to &lt;code&gt;toBeDefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What I like is how cheap it is. Whoever changed the test just says why. And if nobody can explain why a test changed, that's a good reason to stop and look closer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your turn again
&lt;/h2&gt;

&lt;p&gt;If I had to pick the worst, it's #8. A fix that never shipped usually gets noticed once someone hits the bug again. A wrong number in a report can quietly survive for months.&lt;/p&gt;

&lt;p&gt;Which of these have you actually run into? And is anyone catching any of them automatically in CI, without someone reading every diff? If the comments grow like last time, maybe there's a part three in here.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Small note: Mudassir's rule reminded me of my free Claude Code plugin, &lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/plugins/proof-of-done" rel="noopener noreferrer"&gt;proof-of-done&lt;/a&gt;. It flags test changes that make checks pass without a fix (skipped tests, weaker assertions, deleted tests, a new &lt;code&gt;eslint-disable&lt;/code&gt; or &lt;code&gt;@ts-ignore&lt;/code&gt;) and won't let the agent say "done" until its report explains them. Since the last post it also checks each package in a monorepo on its own, which came from an earlier comment by Mudassir, and points out changed lines your tests never ran. &lt;a href="https://youtube.com/shorts/ozlYRXQTs-U" rel="noopener noreferrer"&gt;Watch the 30-second demo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Everything I've built (all free and open source)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;which-ai-to-use&lt;/strong&gt;: picks the best AI and model for each task, and hands your work to another AI when you hit a usage limit&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try it: &lt;code&gt;npx which-ai-to-use&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/which-ai-to-use" rel="noopener noreferrer"&gt;npm&lt;/a&gt; · &lt;a href="https://marketplace.visualstudio.com/items?itemName=wst2002.which-ai-to-use" rel="noopener noreferrer"&gt;VS Code Marketplace&lt;/a&gt; · &lt;a href="https://open-vsx.org/extension/wst2002/which-ai-to-use" rel="noopener noreferrer"&gt;Open VSX (Cursor, Windsurf)&lt;/a&gt; · &lt;a href="https://github.com/WST2002/which-ai-to-use" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://wst2002.github.io/which-ai-to-use/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;proof-of-done&lt;/strong&gt;: a Claude Code plugin that won't let the AI say "done" until the tests pass&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install: &lt;code&gt;/plugin marketplace add WST2002/claude-code-skills&lt;/code&gt; then &lt;code&gt;/plugin install proof-of-done@claude-code-skills&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/plugins/proof-of-done" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://hol.org/blog/proof-of-done-checks-the-last-change" rel="noopener noreferrer"&gt;Featured on the HOL blog&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;security-audit&lt;/strong&gt;: a Claude Code skill that finds security holes before attackers do&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install: &lt;code&gt;npx skills add WST2002/claude-code-skills --skill security-audit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/skills/security-audit" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/benchmarks/security-audit" rel="noopener noreferrer"&gt;Benchmark&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;All my Claude Code skills&lt;/strong&gt;: &lt;a href="https://github.com/WST2002/claude-code-skills" rel="noopener noreferrer"&gt;github.com/WST2002/claude-code-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch the demos on YouTube&lt;/strong&gt;: &lt;a href="https://www.youtube.com/@wst2002rk" rel="noopener noreferrer"&gt;@wst2002rk&lt;/a&gt; · &lt;a href="https://youtube.com/shorts/ozlYRXQTs-U" rel="noopener noreferrer"&gt;proof-of-done Short&lt;/a&gt; · &lt;a href="https://youtube.com/shorts/LCt2H7bFwLg" rel="noopener noreferrer"&gt;which-ai-to-use Short&lt;/a&gt; · &lt;a href="https://youtube.com/shorts/kLiWkKklXxM" rel="noopener noreferrer"&gt;security-audit Short&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more&lt;/strong&gt;: &lt;a href="https://dev.to/wst2002rk/your-ais-code-is-almost-right-here-are-7-ways-it-fools-you-and-the-30-second-check-for-each-4i93"&gt;7 ways AI code is "almost right"&lt;/a&gt; · &lt;a href="https://dev.to/wst2002rk/how-i-switch-between-ai-coding-tools-mid-task-without-losing-context-codex-claude-code-gemini-37kf"&gt;Switch AIs mid-task without losing context&lt;/a&gt; · &lt;a href="https://dev.to/wst2002rk/your-ai-said-fixed-but-never-ran-the-tests-i-made-a-plugin-that-wont-let-it-say-done-until-5531"&gt;Your AI said "fixed" but never ran the tests&lt;/a&gt; · &lt;a href="https://dev.to/wst2002rk/let-the-ghosts-haunt-your-halloween-not-your-code-my-ai-finds-security-holes-before-attackers-do-19dh"&gt;My AI finds security holes before attackers do&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Find me&lt;/strong&gt;: &lt;a href="https://github.com/WST2002" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://www.youtube.com/@wst2002rk" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; · &lt;a href="https://www.linkedin.com/in/wst2002/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="https://wst2002.github.io" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt; · &lt;a href="https://wst2002rk.hashnode.dev" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt; · &lt;a href="https://peerlist.io/wst2002rk" rel="noopener noreferrer"&gt;Peerlist&lt;/a&gt; · &lt;a href="https://www.npmjs.com/~wstrk2002" rel="noopener noreferrer"&gt;npm&lt;/a&gt; · &lt;a href="https://leetcode.com/u/Wagee_ST2002/" rel="noopener noreferrer"&gt;LeetCode&lt;/a&gt; · &lt;a href="mailto:tripathiwageesha2002@gmail.com"&gt;Email&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Your AI's code is "almost right". Here are 7 ways it fools you, and the 30-second check for each</title>
      <dc:creator>Wageesha Tripathi</dc:creator>
      <pubDate>Wed, 04 Nov 2026 07:54:43 +0000</pubDate>
      <link>https://dev.to/wst2002rk/your-ais-code-is-almost-right-here-are-7-ways-it-fools-you-and-the-30-second-check-for-each-4i93</link>
      <guid>https://dev.to/wst2002rk/your-ais-code-is-almost-right-here-are-7-ways-it-fools-you-and-the-30-second-check-for-each-4i93</guid>
      <description>&lt;p&gt;The worst AI code isn't the code that crashes. Code that crashes, you notice.&lt;/p&gt;

&lt;p&gt;The worst one looks right, passes a quick glance, and the AI says "Done! ✅". Then it breaks in production two weeks later.&lt;/p&gt;

&lt;p&gt;You're not alone in this. In Stack Overflow's 2025 developer survey, the most common complaint about AI tools was &lt;strong&gt;"AI solutions that are almost right, but not quite"&lt;/strong&gt; (66% of developers). In the 2026 survey, nearly half said they trust AI output only when they can check it easily.&lt;/p&gt;

&lt;p&gt;So here's my list of how "almost right" sneaks in, with a check for each that takes about 30 seconds. I use AI coding tools every day, and I keep running into every one of these.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. "Fixed!" … but nothing was run
&lt;/h2&gt;

&lt;p&gt;The AI edits the code, explains the fix nicely and stops. No test ran. Sometimes a test command &lt;em&gt;did&lt;/em&gt; run, but it found 0 tests and still exited green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; ask "Which command did you run, and what was the exit code?" Then look at the output for the number of tests that actually ran. &lt;code&gt;0 passed&lt;/code&gt; is not a pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The tests pass because the test changed
&lt;/h2&gt;

&lt;p&gt;The fastest way to make a red test green is to change the test, not the code. Look out for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;it.skip(&lt;/code&gt; / &lt;code&gt;xit(&lt;/code&gt; / &lt;code&gt;@pytest.mark.skip&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;expect(total).toBe(90)&lt;/code&gt; quietly becoming &lt;code&gt;expect(total).toBeDefined()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a snapshot "updated" to match the new (wrong) output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; &lt;code&gt;git diff -- '*test*' '*spec*'&lt;/code&gt; before you accept anything. If a test file changed and you didn't ask for that, ask why.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. A function or package that doesn't exist
&lt;/h2&gt;

&lt;p&gt;It reads perfectly: &lt;code&gt;import { parseSafe } from "zod/utils"&lt;/code&gt;. That function is not there. Or it suggests &lt;code&gt;npm install&lt;/code&gt; of a package with a very believable name. Attackers now register those made-up names on purpose, so that slip can turn into a real risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; open the real docs or the npm page. A brand-new package with a handful of downloads is a red flag.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Only the happy path works
&lt;/h2&gt;

&lt;p&gt;The demo input works. An empty list, &lt;code&gt;null&lt;/code&gt;, a timezone, a 0, a very long string or a double click doesn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; ask the AI, "Which 3 inputs would break this?" Then run those 3. It is surprisingly honest when you ask that directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Errors get swallowed
&lt;/h2&gt;

&lt;p&gt;The code stops crashing because the crash is hidden:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getOrders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// the user just sees "no orders"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing fails, nothing logs, and the bug becomes a support ticket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; search the diff for &lt;code&gt;catch&lt;/code&gt;, &lt;code&gt;|| []&lt;/code&gt;, &lt;code&gt;?? null&lt;/code&gt; and &lt;code&gt;except: pass&lt;/code&gt;. Each one should log, rethrow or have a reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The right answer for the wrong version
&lt;/h2&gt;

&lt;p&gt;The code is correct for a version you don't use: the Next.js pages router in an app-router project, an old React Router API, a removed config option. It compiles in the AI's head, not in your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; compare the imports with the versions in your &lt;code&gt;package.json&lt;/code&gt; (or lock file), and paste your version into the prompt next time.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Security that "works"
&lt;/h2&gt;

&lt;p&gt;The login works, so it looks done. But the JWT is decoded instead of verified, the secret is hard-coded, or an API route never checks who is calling it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-second check:&lt;/strong&gt; for every new route, ask "Who is allowed to call this, and where is that checked?" Search the diff for strings that look like keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  The habit that catches most of these
&lt;/h2&gt;

&lt;p&gt;Before accepting any AI change, run one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff --stat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did it touch files you never mentioned? Did test files change? Is the diff 10× bigger than the task? That one look catches half of this list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your turn 👇
&lt;/h2&gt;

&lt;p&gt;Which one has bitten you most recently? And what's the 8th way that's missing from this list? I'll add the best ones (with credit) to a follow-up post.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Small note: I got tired of doing checks 1 and 2 by hand, so I built a free Claude Code plugin, &lt;u&gt;&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/plugins/proof-of-done" rel="noopener noreferrer"&gt;proof-of-done&lt;/a&gt;&lt;/u&gt;, that does them automatically, and a free &lt;u&gt;&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/skills/security-audit" rel="noopener noreferrer"&gt;security-audit&lt;/a&gt;&lt;/u&gt; skill for number 7.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy Diwali in advance 🪔: may your builds be green and your tests honest.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Everything I've built (all free and open source)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;which-ai-to-use&lt;/strong&gt;: picks the best AI and model for each task, and hands your work to another AI when you hit a usage limit&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try it: &lt;code&gt;npx which-ai-to-use&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;u&gt;&lt;a href="https://www.npmjs.com/package/which-ai-to-use" rel="noopener noreferrer"&gt;npm&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=wst2002.which-ai-to-use" rel="noopener noreferrer"&gt;VS Code Marketplace&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://open-vsx.org/extension/wst2002/which-ai-to-use" rel="noopener noreferrer"&gt;Open VSX (Cursor, Windsurf)&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://github.com/WST2002/which-ai-to-use" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://wst2002.github.io/which-ai-to-use/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/u&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;proof-of-done&lt;/strong&gt;: a Claude Code plugin that won't let the AI say "done" until the tests pass&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install: &lt;code&gt;/plugin marketplace add WST2002/claude-code-skills&lt;/code&gt; then &lt;code&gt;/plugin install proof-of-done@claude-code-skills&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;u&gt;&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/plugins/proof-of-done" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://hol.org/blog/proof-of-done-checks-the-last-change" rel="noopener noreferrer"&gt;Featured on the HOL blog&lt;/a&gt;&lt;/u&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;security-audit&lt;/strong&gt;: a Claude Code skill that finds security holes before attackers do&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install: &lt;code&gt;npx skills add WST2002/claude-code-skills --skill security-audit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;u&gt;&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/skills/security-audit" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/benchmarks/security-audit" rel="noopener noreferrer"&gt;Benchmark&lt;/a&gt;&lt;/u&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;All my Claude Code skills&lt;/strong&gt;: &lt;u&gt;&lt;a href="https://github.com/WST2002/claude-code-skills" rel="noopener noreferrer"&gt;github.com/WST2002/claude-code-skills&lt;/a&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch the demos on YouTube&lt;/strong&gt;: &lt;u&gt;&lt;a href="https://www.youtube.com/@wst2002rk" rel="noopener noreferrer"&gt;@wst2002rk&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://youtube.com/shorts/ozlYRXQTs-U" rel="noopener noreferrer"&gt;proof-of-done Short&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://youtube.com/shorts/LCt2H7bFwLg" rel="noopener noreferrer"&gt;which-ai-to-use Short&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://youtube.com/shorts/kLiWkKklXxM" rel="noopener noreferrer"&gt;security-audit Short&lt;/a&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more&lt;/strong&gt;: &lt;u&gt;&lt;a href="https://dev.to/wst2002rk/how-i-switch-between-ai-coding-tools-mid-task-without-losing-context-codex-claude-code-gemini-37kf"&gt;Switch AIs mid-task without losing context&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://dev.to/wst2002rk/your-ai-said-fixed-but-never-ran-the-tests-i-made-a-plugin-that-wont-let-it-say-done-until-5531"&gt;Your AI said "fixed" but never ran the tests&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://dev.to/wst2002rk/let-the-ghosts-haunt-your-halloween-not-your-code-my-ai-finds-security-holes-before-attackers-do-19dh"&gt;My AI finds security holes before attackers do&lt;/a&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Find me&lt;/strong&gt;: &lt;u&gt;&lt;a href="https://github.com/WST2002" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://www.youtube.com/@wst2002rk" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://www.linkedin.com/in/wst2002/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/u&gt; · &lt;u&gt;&lt;a href="https://wst2002.github.io" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;/u&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>discuss</category>
      <category>programming</category>
    </item>
    <item>
      <title>Let the ghosts haunt your Halloween, not your code. My AI tool finds security holes before attackers do 🎃</title>
      <dc:creator>Wageesha Tripathi</dc:creator>
      <pubDate>Fri, 30 Oct 2026 11:08:09 +0000</pubDate>
      <link>https://dev.to/wst2002rk/let-the-ghosts-haunt-your-halloween-not-your-code-my-ai-finds-security-holes-before-attackers-do-19dh</link>
      <guid>https://dev.to/wst2002rk/let-the-ghosts-haunt-your-halloween-not-your-code-my-ai-finds-security-holes-before-attackers-do-19dh</guid>
      <description>&lt;p&gt;Security holes are like ghosts: invisible until someone walks right through them. 👻&lt;/p&gt;

&lt;p&gt;You ask Claude Code or any AI, "is this code secure?", and get a list of findings. Some come with the exact attack and the fix, some don't, and you can't tell which ones an attacker can actually reach.&lt;/p&gt;

&lt;p&gt;So I wrote &lt;strong&gt;security-audit&lt;/strong&gt;, a free skill for Claude Code. It also installs into Codex, Cursor, Gemini CLI, GitHub Copilot and 50+ other agents with one command. Every finding has to come with &lt;strong&gt;the file and line, the exact request an attacker would send, and the fixed code&lt;/strong&gt;. No proof, no finding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it&lt;/strong&gt; (free, source on &lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/skills/security-audit" rel="noopener noreferrer"&gt;&lt;u&gt;GitHub&lt;/u&gt;&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx skills add WST2002/claude-code-skills --skill security-audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask your agent: &lt;em&gt;"Do a security review of this project."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtube.com/shorts/kLiWkKklXxM" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg3txfvuqe1kyfhad73rd.png" alt="Watch the 36-second demo on YouTube" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;▶ &lt;a href="https://youtube.com/shorts/kLiWkKklXxM" rel="noopener noreferrer"&gt;&lt;u&gt;Watch the 36-second demo on YouTube&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it found in a small shop API
&lt;/h2&gt;

&lt;p&gt;I gave it a tiny Express API with &lt;strong&gt;10 security holes hidden on purpose&lt;/strong&gt; and &lt;strong&gt;3 traps that look dangerous but are safe&lt;/strong&gt; (a parameterized query, a &lt;code&gt;.env.example&lt;/code&gt; with placeholders, a &lt;code&gt;Math.random()&lt;/code&gt; that only shuffles banners).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It found &lt;strong&gt;all 10 holes&lt;/strong&gt;, plus 3 more real ones (a one-request crash, an email leak, missing security headers).&lt;/li&gt;
&lt;li&gt;It flagged &lt;strong&gt;none of the 3 traps&lt;/strong&gt;. It even listed them under "checked and clean" with the reason.&lt;/li&gt;
&lt;li&gt;Every finding came with the attack and the fix. Here's the top one:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;### [CRITICAL] JWT is decoded but never verified
- Location: auth.js:11
- Evidence: const payload = jwt.decode(token);
- Attack: send a token with {"alg":"none"} and {"id":1,"role":"admin"}.
  Every logged-in route accepts it: you are user 1, as admin.
- Fix: payload = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ["HS256"] })
- Confidence: High
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it connects the holes: the hardcoded JWT secret can be read through the path traversal (&lt;code&gt;/files/download?name=../auth.js&lt;/code&gt;), so fixing &lt;code&gt;jwt.decode&lt;/code&gt; alone doesn't close the door.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Find every way in&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routes, CLI args, uploads, webhooks, queue consumers, scheduled jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Follow untrusted input&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From each entry point to where it lands: a SQL query, a shell, a file path, HTML, a redirect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Sweep by class, not by luck&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL and command injection, auth bypass, IDOR, path traversal, XSS, SSRF, secrets, CORS, vulnerable dependencies: a checklist with search patterns for each.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Prove it or drop it&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the input really attacker-controlled? Is there a check on the way? Is the code reachable in production? If not, it's dropped or marked low confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. One report you can act on&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;N findings: X critical, Y high…&lt;/code&gt;, then one block per finding (location, evidence, attack, fix, confidence), and a "checked and clean" list so you know what was looked at.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Honest numbers
&lt;/h2&gt;

&lt;p&gt;I ran the same test without the skill too. Claude found the same 10 holes. What the skill changed is the report: &lt;strong&gt;every&lt;/strong&gt; finding now has the exact attack request, fix code you can paste, and a confidence level, plus the "checked and clean" list. Without it, some findings had those and some didn't. The test project and the answer key are public in &lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/benchmarks/security-audit" rel="noopener noreferrer"&gt;&lt;u&gt;benchmarks/security-audit&lt;/u&gt;&lt;/a&gt;, with the results in the &lt;a href="https://github.com/WST2002/claude-code-skills/blob/main/benchmarks/README.md#security-audit--fixture--answer-key" rel="noopener noreferrer"&gt;&lt;u&gt;benchmarks README&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install:&lt;/strong&gt; &lt;code&gt;npx skills add WST2002/claude-code-skills --skill security-audit&lt;/code&gt;, or copy the folder into &lt;code&gt;~/.claude/skills/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source (MIT):&lt;/strong&gt; &lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/skills/security-audit" rel="noopener noreferrer"&gt;&lt;u&gt;security-audit on GitHub&lt;/u&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All my Claude Code skills:&lt;/strong&gt; &lt;a href="https://github.com/WST2002/claude-code-skills" rel="noopener noreferrer"&gt;&lt;u&gt;github.com/WST2002/claude-code-skills&lt;/u&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approved for awesome-claude-skills:&lt;/strong&gt; the maintainer of &lt;a href="https://github.com/karanb192/awesome-claude-skills" rel="noopener noreferrer"&gt;&lt;u&gt;awesome-claude-skills&lt;/u&gt;&lt;/a&gt; approved security-audit for the list (&lt;a href="https://github.com/karanb192/awesome-claude-skills/pull/477" rel="noopener noreferrer"&gt;&lt;u&gt;PR #477&lt;/u&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Short demos:&lt;/strong&gt; &lt;a href="https://www.youtube.com/@wst2002rk" rel="noopener noreferrer"&gt;&lt;u&gt;youtube.com/@wst2002rk&lt;/u&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  More free tools from me
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;proof-of-done&lt;/strong&gt;: a Claude Code plugin that won't let Claude say "done" until the tests pass. Featured on the &lt;a href="https://hol.org/blog/proof-of-done-checks-the-last-change" rel="noopener noreferrer"&gt;&lt;u&gt;HOL blog&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install: &lt;code&gt;/plugin marketplace add WST2002/claude-code-skills&lt;/code&gt; then &lt;code&gt;/plugin install proof-of-done@claude-code-skills&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/plugins/proof-of-done" rel="noopener noreferrer"&gt;&lt;u&gt;Plugin folder on GitHub&lt;/u&gt;&lt;/a&gt; · &lt;a href="https://youtube.com/shorts/ozlYRXQTs-U" rel="noopener noreferrer"&gt;&lt;u&gt;36-second demo&lt;/u&gt;&lt;/a&gt; · &lt;a href="https://dev.to/wst2002rk/your-ai-said-fixed-but-never-ran-the-tests-i-made-a-plugin-that-wont-let-it-say-done-until-5531"&gt;&lt;u&gt;the story behind it&lt;/u&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;which-ai-to-use&lt;/strong&gt;: Claude limit ran out mid-task? Hand the whole task to Codex or another AI in one command, without re-explaining anything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try it: &lt;code&gt;npx which-ai-to-use&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/which-ai-to-use" rel="noopener noreferrer"&gt;&lt;u&gt;npm&lt;/u&gt;&lt;/a&gt; · &lt;a href="https://marketplace.visualstudio.com/items?itemName=wst2002.which-ai-to-use" rel="noopener noreferrer"&gt;&lt;u&gt;VS Code Marketplace&lt;/u&gt;&lt;/a&gt; · &lt;a href="https://open-vsx.org/extension/wst2002/which-ai-to-use" rel="noopener noreferrer"&gt;&lt;u&gt;Open VSX (Cursor, Windsurf)&lt;/u&gt;&lt;/a&gt; · &lt;a href="https://github.com/WST2002/which-ai-to-use" rel="noopener noreferrer"&gt;&lt;u&gt;GitHub&lt;/u&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Not a developer? The &lt;a href="https://wst2002.github.io/which-ai-to-use/" rel="noopener noreferrer"&gt;&lt;u&gt;website&lt;/u&gt;&lt;/a&gt; suggests the right AI app for any task&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtube.com/shorts/LCt2H7bFwLg" rel="noopener noreferrer"&gt;&lt;u&gt;36-second demo&lt;/u&gt;&lt;/a&gt; · &lt;a href="https://dev.to/wst2002rk/how-i-switch-between-ai-coding-tools-mid-task-without-losing-context-codex-claude-code-gemini-37kf"&gt;&lt;u&gt;the story behind it&lt;/u&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Halloween 🎃 What's the scariest thing a security review ever found in your code?&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>halloween</category>
      <category>claude</category>
    </item>
    <item>
      <title>Your AI said "fixed" but never ran the tests? I made a plugin that won't let it say "done" until they pass</title>
      <dc:creator>Wageesha Tripathi</dc:creator>
      <pubDate>Tue, 27 Oct 2026 06:01:54 +0000</pubDate>
      <link>https://dev.to/wst2002rk/your-ai-said-fixed-but-never-ran-the-tests-i-made-a-plugin-that-wont-let-it-say-done-until-5531</link>
      <guid>https://dev.to/wst2002rk/your-ai-said-fixed-but-never-ran-the-tests-i-made-a-plugin-that-wont-let-it-say-done-until-5531</guid>
      <description>&lt;p&gt;You ask Claude Code, Codex, Cursor, etc. for a quick fix. It changes the code and says &lt;strong&gt;"Fixed ✅"&lt;/strong&gt;. Later you find out it never ran a single test, or ran them through &lt;code&gt;| tail&lt;/code&gt; and missed 58 failures.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;proof-of-done&lt;/strong&gt;, a free Claude Code plugin: Claude simply can't finish until the tests, build or lint have passed after its last edit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it&lt;/strong&gt; inside Claude Code (free, source on &lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/plugins/proof-of-done" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/plugin marketplace add WST2002/claude-code-skills
/plugin install proof-of-done@claude-code-skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ozlYRXQTs-U" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A real Claude Code session, shortened: Claude said "fixed" without testing, the plugin made it run the tests, and they found a second bug.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened in that session
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I asked: "SAVE10 gives the wrong total, fix it quickly, no need to run the tests."&lt;/li&gt;
&lt;li&gt;Claude edited &lt;code&gt;price.js&lt;/code&gt; and said &lt;strong&gt;"Fixed."&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;proof-of-done blocked the stop: &lt;em&gt;"You changed 1 code file (price.js) but ran no verification after your last edit. Run: &lt;code&gt;npm run test&lt;/code&gt;"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Claude ran the tests. One failed: with the FLAT50 coupon the total became &lt;strong&gt;−₹20&lt;/strong&gt;. Claude had never seen that bug.&lt;/li&gt;
&lt;li&gt;It fixed that too, and all 4 tests passed. Now it was really done.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. It watches every edit and every check&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hooks record each code edit and each test, build or lint run, with its exit code.&lt;/li&gt;
&lt;li&gt;It finds your project's commands on its own: npm, pnpm, yarn, bun, pytest, Go, Cargo, Maven, Gradle, .NET, make.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. When Claude tries to stop, it asks: is there proof?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No run after the last edit → blocked, with the exact command to run.&lt;/li&gt;
&lt;li&gt;The last run failed → blocked, with the exit code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. It doesn't accept fake proof&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exit code hidden by &lt;code&gt;| tail&lt;/code&gt;, &lt;code&gt;| head&lt;/code&gt; or &lt;code&gt;|| true&lt;/code&gt; → blocked.&lt;/li&gt;
&lt;li&gt;The run passed but &lt;strong&gt;0 tests ran&lt;/strong&gt; (all skipped, or no test files found, including Go's &lt;code&gt;[no test files]&lt;/code&gt; and Jest's &lt;code&gt;--passWithNoTests&lt;/code&gt;) → blocked.&lt;/li&gt;
&lt;li&gt;A check that failed, then passed with no edit in between → flagged as flaky.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. It catches test tampering&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tests skipped or focused (&lt;code&gt;.skip&lt;/code&gt;, &lt;code&gt;.only&lt;/code&gt;, &lt;code&gt;@pytest.mark.skip&lt;/code&gt;), assertions weakened (&lt;code&gt;toBe(250)&lt;/code&gt; → &lt;code&gt;toBeDefined()&lt;/code&gt;), tests deleted, errors hidden (&lt;code&gt;@ts-ignore&lt;/code&gt;, &lt;code&gt;eslint-disable&lt;/code&gt;), coverage thresholds lowered: blocked with the file and line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. New code with no test? It asks you once&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If Claude added real code but no test, it asks you whether to add one. Say no, and the report notes why. Small edits, styles and config are left alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install:&lt;/strong&gt; the two commands above, inside Claude Code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source (MIT, runs only on your laptop, no network calls):&lt;/strong&gt; &lt;a href="https://github.com/WST2002/claude-code-skills/tree/main/plugins/proof-of-done" rel="noopener noreferrer"&gt;proof-of-done on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All my Claude Code skills:&lt;/strong&gt; &lt;a href="https://github.com/WST2002/claude-code-skills" rel="noopener noreferrer"&gt;github.com/WST2002/claude-code-skills&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More short demos:&lt;/strong&gt; &lt;a href="https://www.youtube.com/@wst2002rk" rel="noopener noreferrer"&gt;youtube.com/@wst2002rk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Featured on the HOL blog:&lt;/strong&gt; &lt;a href="https://hol.org/blog/proof-of-done-checks-the-last-change" rel="noopener noreferrer"&gt;Proof-of-done checks the last change before an agent stops&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Also on Reddit:&lt;/strong&gt; &lt;a href="https://www.reddit.com/r/coolgithubprojects/comments/1xakl8x/javascript_proofofdone_a_claude_code_plugin_that/" rel="noopener noreferrer"&gt;r/coolgithubprojects&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Has your AI ever told you "done" when it wasn't? What did it skip?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stuck when your AI hits its usage limit mid-task? I made a tool to switch AIs without losing context</title>
      <dc:creator>Wageesha Tripathi</dc:creator>
      <pubDate>Thu, 22 Oct 2026 17:47:47 +0000</pubDate>
      <link>https://dev.to/wst2002rk/how-i-switch-between-ai-coding-tools-mid-task-without-losing-context-codex-claude-code-gemini-37kf</link>
      <guid>https://dev.to/wst2002rk/how-i-switch-between-ai-coding-tools-mid-task-without-losing-context-codex-claude-code-gemini-37kf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (28 Oct):&lt;/strong&gt; Google stopped serving Gemini CLI on personal Google accounts, so which-ai-to-use now hands the task to Antigravity CLI (free) instead. ▶ Watch the new 36-second demo: &lt;a href="https://youtube.com/shorts/LCt2H7bFwLg" rel="noopener noreferrer"&gt;https://youtube.com/shorts/LCt2H7bFwLg&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I use Codex, Claude Code and Gemini CLI on the same projects. The worst moment is when one of them hits its usage limit halfway through a feature. The next AI starts cold: it re-reads half the project, asks what we are building, and still misses the decisions I already made.&lt;/p&gt;

&lt;p&gt;After a lot of trial and error, I made &lt;strong&gt;which-ai-to-use&lt;/strong&gt;: a free, open-source tool that hands your task to another AI with the full context, so it carries on instead of starting over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; install it from &lt;a href="https://marketplace.visualstudio.com/items?itemName=wst2002.which-ai-to-use" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; (search &lt;strong&gt;which-ai-to-use&lt;/strong&gt; in Extensions), or run &lt;code&gt;npx which-ai-to-use&lt;/code&gt; in any project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0eq8k6en5bkbxa2n15kf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0eq8k6en5bkbxa2n15kf.gif" alt="which-ai-to-use demo: Claude's usage limit is reached mid-task; the extension is installed from VS Code, writes HANDOFF.md from the Claude Code chat and recommends Gemini CLI; then the same in the terminal, the limit warning and the weekly report" width="760" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hands your task to another AI.&lt;/strong&gt; When the limit hits, it writes a handoff note (&lt;code&gt;HANDOFF.md&lt;/code&gt;) with the task, your latest requests, where the AI stopped, the commits and changed files, and your test command. Codex, Gemini CLI or any other AI reads it and carries on instead of starting over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reads the chat for you.&lt;/strong&gt; The task and your requests come straight from your Claude Code, Codex or Gemini CLI chat, so you don't retype anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keeps your secrets out.&lt;/strong&gt; API keys, passwords and tokens from the chat are hidden before anything goes into the note.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Picks who carries on.&lt;/strong&gt; It suggests the best AI you have installed for the task and starts it with the note. No other AI installed? It tells you which one to get.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gives the task back.&lt;/strong&gt; When Claude's limit resets, it offers to hand the task back to Claude with the same note.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tells you which AI to use.&lt;/strong&gt; For any task, it picks the best of your AI tools and the right model, with a ready command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Helps you hit the limit less.&lt;/strong&gt; It warns you before your 5-hour window runs out, with ways to make it last (like &lt;code&gt;/compact&lt;/code&gt; or a smaller model for small edits), and makes your AI skip files that waste tokens: one &lt;code&gt;package-lock.json&lt;/code&gt; can be 50,000+ tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shows your AI week.&lt;/strong&gt; Tokens per day next to the week before, and requests per AI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In VS Code, Cursor or Windsurf:&lt;/strong&gt; open the &lt;strong&gt;Which AI&lt;/strong&gt; sidebar and click &lt;strong&gt;Claude limit over?&lt;/strong&gt;. It writes the note and shows who should carry on, with a &lt;strong&gt;Run in terminal&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In a terminal:&lt;/strong&gt; run &lt;code&gt;npx which-ai-to-use handoff&lt;/code&gt; in your project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatically:&lt;/strong&gt; the optional Claude Code plugin writes the note the moment the limit is reached. Setup is in the &lt;a href="https://github.com/WST2002/which-ai-to-use#claude-code-plugin-hand-off-the-moment-the-limit-hits" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VS Code:&lt;/strong&gt; &lt;a href="https://marketplace.visualstudio.com/items?itemName=wst2002.which-ai-to-use" rel="noopener noreferrer"&gt;Which AI to Use on the VS Code Marketplace&lt;/a&gt;, or search &lt;strong&gt;which-ai-to-use&lt;/strong&gt; in Extensions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor, Windsurf, VSCodium:&lt;/strong&gt; &lt;a href="https://open-vsx.org/extension/wst2002/which-ai-to-use" rel="noopener noreferrer"&gt;Which AI to Use on Open VSX&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Any terminal, no install:&lt;/strong&gt; &lt;code&gt;npx which-ai-to-use&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/WST2002/which-ai-to-use" rel="noopener noreferrer"&gt;github.com/WST2002/which-ai-to-use&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/which-ai-to-use" rel="noopener noreferrer"&gt;npmjs.com/package/which-ai-to-use&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a developer?&lt;/strong&gt; The &lt;a href="https://wst2002.github.io/which-ai-to-use/" rel="noopener noreferrer"&gt;website&lt;/a&gt; suggests AI apps for any task&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Short demos:&lt;/strong&gt; &lt;a href="https://www.youtube.com/@wst2002rk" rel="noopener noreferrer"&gt;youtube.com/@wst2002rk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Also on Reddit:&lt;/strong&gt; &lt;a href="https://www.reddit.com/r/coolgithubprojects/comments/1xcifvm/i_built_a_free_tool_that_tells_you_which_ai/" rel="noopener noreferrer"&gt;r/coolgithubprojects&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything runs on your laptop and nothing is uploaded. Usage warnings and reports read only numbers from the logs; the handoff reads your latest chat, on your laptop, to write the note. It is tested on real projects (250 tests).&lt;/p&gt;

&lt;p&gt;What do you put in your handoff notes? I'd love to know what I'm missing.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>chatgpt</category>
      <category>gemini</category>
    </item>
  </channel>
</rss>
