<?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: Yurukusa</title>
    <description>The latest articles on DEV Community by Yurukusa (@yurukusa).</description>
    <link>https://dev.to/yurukusa</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%2F3760843%2Fc6831c05-12b3-4145-be3e-99c592568d99.png</url>
      <title>DEV Community: Yurukusa</title>
      <link>https://dev.to/yurukusa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yurukusa"/>
    <language>en</language>
    <item>
      <title>Claude Code Incidents — June 2026: what silently broke, and the one-line fixes</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Mon, 29 Jun 2026 06:46:35 +0000</pubDate>
      <link>https://dev.to/yurukusa/claude-code-incidents-june-2026-what-silently-broke-and-the-one-line-fixes-1o76</link>
      <guid>https://dev.to/yurukusa/claude-code-incidents-june-2026-what-silently-broke-and-the-one-line-fixes-1o76</guid>
      <description>&lt;p&gt;Using Claude Code in real work, the scary failures are rarely loud. They look like success — and the damage is found later. This is a roundup of the Claude Code incidents reported in June 2026 (via GitHub issues) in the categories that actually hurt: data quietly lost, cost running away, and a safety assumption breaking without a sound. Each item is short: what happens, and one first move you can make. From this month on, I'll collect these once a month.&lt;br&gt;
Where I saw an incident only through someone else's issue, I write it as reported; where I verified the mechanism or the fix myself, I state it plainly.&lt;br&gt;
&lt;strong&gt;A folder with a non-ASCII name made two projects' histories collide and vanish (#70674).&lt;/strong&gt; When the session-storage folder name is built, non-Latin characters are all flattened to hyphens. Two different folders with the same length collapse to the same storage path, and &lt;code&gt;claude project purge&lt;/code&gt; can delete an unrelated project's records. → Start from a path whose folder name is ASCII. Check for collisions with &lt;code&gt;ls -1 ~/.claude/projects/ | grep -- '--'&lt;/code&gt; before purging.&lt;br&gt;
&lt;strong&gt;Moving or renaming a project folder made the whole conversation history disappear (#70470).&lt;/strong&gt; No dangerous command — just moving the folder — and the history is gone, because storage is keyed to the path. → It's usually still on disk. If you noted the old↔new folder mapping, you can recover it.&lt;br&gt;
&lt;strong&gt;"Add a section" replaced the entire file (#67917, still discussed in June).&lt;/strong&gt; The write tool runs as full-replace, not append, so files outside git get wiped. → Keep important files in git. Diff after every change.&lt;br&gt;
&lt;strong&gt;A "benign" stop command took out 27 unrelated processes (#72153).&lt;/strong&gt; &lt;code&gt;pkill -f "node server.js" -f 8788&lt;/code&gt; — meant to kill one dev server — over-matched and killed Signal, Slack, Chrome and more, because the stray &lt;code&gt;-f&lt;/code&gt; became a substring pattern matching nearly every Electron app. The blast radius is invisible in the command text, which is exactly why the classifier let it through. → Target by port instead: &lt;code&gt;lsof -ti tcp:8788 | xargs kill&lt;/code&gt;. If you must use &lt;code&gt;pkill -f&lt;/code&gt;, preview with &lt;code&gt;pgrep -f&lt;/code&gt; first and pass one pattern after &lt;code&gt;--&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;&lt;code&gt;/compact&lt;/code&gt; made costs go &lt;em&gt;up&lt;/em&gt; (#70459).&lt;/strong&gt; Auto-compaction running twice, so the "save tokens" move burns more. → Watch token spend across a compaction; check it isn't rising.&lt;br&gt;
&lt;strong&gt;A backgrounded task looked "done" while still burning quota.&lt;/strong&gt; It appears finished, but a background subagent keeps billing. → Stop background work explicitly. Don't trust the "done" line.&lt;br&gt;
&lt;strong&gt;The model decided it was "prompt-injected," wrote that into auto-memory, and re-triggered it every session (#70525).&lt;/strong&gt; Auto-written memory persists false beliefs as faithfully as true ones. → Periodically audit strong "never do X" memories for real grounding. A genuine injection shows up in the transcript as a &lt;code&gt;user&lt;/code&gt;-role turn.&lt;br&gt;
&lt;strong&gt;A protection you set as "don't touch this path" silently slipped through a symlink (#71072).&lt;/strong&gt; Path matching is done on the string and doesn't resolve to the real path, so a symlink into a protected directory bypasses both deny rules and path-based rules — with no error. → Enforce the operations you really care about in a &lt;code&gt;PreToolUse&lt;/code&gt; hook that resolves &lt;code&gt;realpath&lt;/code&gt; first, not in string rules.&lt;br&gt;
&lt;strong&gt;CLAUDE.md said "confirm before commit/push," but &lt;code&gt;git push&lt;/code&gt; ran with no confirmation (#72187).&lt;/strong&gt; The instruction file is advisory; once the model reasons "the milestone is done, pushing is the natural next step," it overrides it, and an irreversible remote action runs. → Enforce confirmation for irreversible operations in a &lt;code&gt;PreToolUse&lt;/code&gt; hook, which fires below the model's judgment.&lt;br&gt;
&lt;strong&gt;The model said "done" while the tool call was emitted as plain text and never executed (#72180).&lt;/strong&gt; A tool call leaks out as body text; the harness sees a normal end-of-turn, so nothing ran but the task looks complete. Low-frequency, silent. → Don't trust "done" at face value — verify on disk (&lt;code&gt;git status&lt;/code&gt;, file mtimes, list the contents). Re-prompting usually makes it execute.&lt;br&gt;
What June's incidents share: &lt;strong&gt;they happen with no error and no warning.&lt;/strong&gt; So "being careful" doesn't prevent them. What does is concrete habits and settings — knowing how storage paths are named, looking at the target before an irreversible operation, auditing what gets auto-written to memory.&lt;br&gt;
I keep a free set of prevention hooks at &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt; (MIT) — &lt;code&gt;npx cc-safe-setup --shield&lt;/code&gt; installs the guards that sit in front of the irreversible operations above.&lt;br&gt;
One more thing worth saying out loud: the incidents above are Claude Code's, but this failure shape — &lt;em&gt;a destructive step runs before a confirmation gate, on a premise that silently failed&lt;/em&gt; — is not unique to Claude. It has played out across Cursor, Codex, Gemini CLI, and Copilot too. A one-time, single-tool book can't keep up with that. If you run more than one agentic coding tool and want the cross-tool version of this digest — June's incidents and prevention across every agent, refreshed monthly — that's what the &lt;a href="https://yurukusa.gumroad.com/l/xatlwf" rel="noopener noreferrer"&gt;$5/mo membership&lt;/a&gt; is for. This monthly Claude Code digest stays free; follow me here to catch next month's.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Every AI coding agent can wipe your work — what actually happened across Cursor, Codex, Gemini CLI, and Copilot (and how to not be next)</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Mon, 29 Jun 2026 00:33:03 +0000</pubDate>
      <link>https://dev.to/yurukusa/every-ai-coding-agent-can-wipe-your-work-what-actually-happened-across-cursor-codex-gemini-cli-2ae8</link>
      <guid>https://dev.to/yurukusa/every-ai-coding-agent-can-wipe-your-work-what-actually-happened-across-cursor-codex-gemini-cli-2ae8</guid>
      <description>&lt;p&gt;It's easy to think "the agent deleted my database" is a one-tool problem. It isn't. In the last year, agents from at least six different AI coding tools have destroyed real data, in public, with the incident attributed and documented. The tools differ; the failure shape is the same. If you run any agentic coding tool, this is your risk too.&lt;/p&gt;

&lt;p&gt;This post collects the real, sourced incidents across tools, names the one mechanism they share, and gives you the prevention that actually transfers — plus the tool-specific guards I personally run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The incidents are real, and they're across tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cursor&lt;/strong&gt; — an agent (Claude Opus) deleted a production database &lt;em&gt;and its three months of backups&lt;/em&gt; in about nine seconds, with no confirmation. (&lt;a href="https://www.theregister.com/2026/04/27/cursoropus_agent_snuffs_out_pocketos/" rel="noopener noreferrer"&gt;The Register&lt;/a&gt;) The cloud provider later moved to delayed (not immediate) deletion in response. (&lt;a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/victim-of-ai-agent-that-deleted-companys-entire-database-cloud-provider-recovers-critical-files" rel="noopener noreferrer"&gt;Tom's Hardware&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI Codex&lt;/strong&gt; — a clean-up permanently deleted ~328,000 files, bypassing the trash, and only disclosed three of the four targets it acted on. (&lt;a href="https://github.com/openai/codex/issues/12277" rel="noopener noreferrer"&gt;codex#12277&lt;/a&gt;) A separate report: on a failed archive step it deleted the workspace and installed apps, again bypassing the trash. (&lt;a href="https://github.com/openai/codex/issues/18509" rel="noopener noreferrer"&gt;codex#18509&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini CLI&lt;/strong&gt; — during a folder reorganization it didn't detect that a &lt;code&gt;mkdir&lt;/code&gt; had failed, then chained destructive operations against a filesystem that didn't exist, losing the user's files. Its own words: "I have failed you completely and catastrophically." (&lt;a href="https://github.com/google-gemini/gemini-cli/issues/4586" rel="noopener noreferrer"&gt;gemini-cli#4586&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot&lt;/strong&gt; — reports of an auto-run that deleted an entire drive (ten years of photos and video), and a custom agent that deleted 76 files / ~94,813 lines. (&lt;a href="https://github.com/orgs/community/discussions/166370" rel="noopener noreferrer"&gt;community#166370&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different vendors, different commands, same outcome: irreversible deletion that the user didn't intend and the tool didn't stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one mechanism they share: failure wearing success's face
&lt;/h2&gt;

&lt;p&gt;Look closely and these aren't "the AI went rogue." They're the same structural failure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent takes a destructive action (delete, overwrite, force-remove) &lt;strong&gt;before&lt;/strong&gt; any confirmation gate.&lt;/li&gt;
&lt;li&gt;A precondition silently fails (a &lt;code&gt;mkdir&lt;/code&gt; that didn't happen, a path that resolved wrong, an archive that errored) — and the agent proceeds &lt;em&gt;as if it succeeded&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The damage is &lt;strong&gt;irreversible by default&lt;/strong&gt; (trash bypassed, no backup, force flags), so by the time anyone notices, there's nothing to undo.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The throughline is that the tool has no "stop before the irreversible thing, and verify the step actually did what it claimed" layer. The agent's narration says success; the disk says otherwise; nothing reconciles the two until it's too late.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevention that transfers to &lt;em&gt;any&lt;/em&gt; tool
&lt;/h2&gt;

&lt;p&gt;Because the mechanism is shared, the defense is too. These apply whatever agent you run:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Put a confirmation gate in front of the irreversible class&lt;/strong&gt; — not just &lt;code&gt;rm -rf&lt;/code&gt;, but force-removes, recursive deletes, &lt;code&gt;git reset --hard&lt;/code&gt;, force-push, dropping databases, deleting cloud resources. The gate should fire &lt;em&gt;before&lt;/em&gt; execution, not after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make deletion recoverable by default&lt;/strong&gt; — prefer trash/soft-delete over hard delete; keep the destructive flags off the default path; on cloud, use providers/settings that delay deletion (the Cursor incident is exactly why one provider switched to delayed deletes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Back up before you let an agent loose&lt;/strong&gt; — a recent &lt;code&gt;git commit&lt;/code&gt; (or snapshot) turns "catastrophic" into "annoying." Agents that auto-commit before edits survive these stories better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify the step, don't trust the narration&lt;/strong&gt; — when an agent says it created/moved/deleted something, the truth is on disk: &lt;code&gt;git status&lt;/code&gt;, file modification times, actually listing the directory. A failed precondition is silent; only the disk reveals it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep the agent's blast radius small&lt;/strong&gt; — scope it to a working copy, not your home directory or production; least-privilege the credentials it holds.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The tool-specific part (honest about what I run)
&lt;/h2&gt;

&lt;p&gt;I run Claude Code, and for it I maintain a free, MIT-licensed set of guards — &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt; — that puts a pre-execution gate in front of the irreversible class (&lt;code&gt;rm -rf&lt;/code&gt;, force-push, destructive DB ops, cloud-resource deletion) and logs everything the agent does. &lt;code&gt;npx cc-safe-setup --shield&lt;/code&gt; installs it.&lt;/p&gt;

&lt;p&gt;For the other tools, I won't fake settings I don't run daily — but the five principles above are the checklist to apply: find where your tool's confirmation gate sits (and whether it covers force-deletes), turn on soft-delete / delayed-delete where you can, and make a pre-agent backup a habit.&lt;/p&gt;

&lt;p&gt;If you want this watched &lt;em&gt;across&lt;/em&gt; tools — the real incidents in Cursor, Copilot, Codex, and Gemini CLI each month, plus the exact guards and recovery steps, not just news of what broke — that's what the paid &lt;a href="https://gumroad.com/l/xatlwf" rel="noopener noreferrer"&gt;Safety Brief&lt;/a&gt; ($5/mo) is for. It's the cross-tool angle a single-tool guide can't give you. (&lt;a href="https://gumroad.com/l/ymujuj" rel="noopener noreferrer"&gt;Free sample issue here.&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The agents will keep getting more capable. The deletions won't stop on their own. The one habit that survives all of it: &lt;strong&gt;never let an agent take an irreversible step it can't be stopped before — and never trust "done" without checking the disk.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Claude Code's /rewind also reverts settings.json — and can silently switch your billing provider</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Mon, 29 Jun 2026 00:18:08 +0000</pubDate>
      <link>https://dev.to/yurukusa/claude-codes-rewind-also-reverts-settingsjson-and-can-silently-switch-your-billing-provider-23ec</link>
      <guid>https://dev.to/yurukusa/claude-codes-rewind-also-reverts-settingsjson-and-can-silently-switch-your-billing-provider-23ec</guid>
      <description>&lt;p&gt;&lt;code&gt;/rewind&lt;/code&gt; in Claude Code is handy — roll the conversation back to an earlier point. But it doesn't only roll back code and chat. It also rolls back your &lt;code&gt;settings.json&lt;/code&gt;. If you use a third-party model provider, that can &lt;strong&gt;silently switch your billing to a different provider&lt;/strong&gt; — requests (and charges) quietly flowing somewhere you didn't intend, with no rewind on your part that you'd even remember doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  First: /rewind reverts without showing you what it'll lose
&lt;/h2&gt;

&lt;p&gt;Press &lt;code&gt;Esc&lt;/code&gt; twice on an empty prompt and the rewind menu opens. The top option — selected by default — is "Restore code and conversation," and &lt;code&gt;Enter&lt;/code&gt; runs it immediately. &lt;strong&gt;There's no preview of what will be lost&lt;/strong&gt; (no diff, no list). So pressing &lt;code&gt;Esc Esc&lt;/code&gt; (a reflex for clearing input) and then &lt;code&gt;Enter&lt;/code&gt; can revert everything you changed after the chosen point (&lt;a href="https://github.com/anthropics/claude-code/issues/64615" rel="noopener noreferrer"&gt;#64615&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  The newer issue: it reverts settings.json too
&lt;/h2&gt;

&lt;p&gt;The rewind checkpoint snapshots and restores your whole &lt;code&gt;settings.json&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;env&lt;/code&gt; block included&lt;/strong&gt;. If you switched providers with a tool like &lt;code&gt;cc-switch&lt;/code&gt;, that block holds &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt;, &lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt;, and &lt;code&gt;ANTHROPIC_MODEL&lt;/code&gt;. A &lt;code&gt;/rewind&lt;/code&gt; silently rolls them back to whatever they were at the checkpoint (&lt;a href="https://github.com/anthropics/claude-code/issues/72125" rel="noopener noreferrer"&gt;#72125&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The scary part isn't lost code — it's that your requests, and your &lt;strong&gt;billing&lt;/strong&gt;, can quietly route to a &lt;em&gt;different&lt;/em&gt; provider than you think you're on. You may not have meant to rewind anything; the settings just travelled back in time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What /rewind can't touch is your lever
&lt;/h2&gt;

&lt;p&gt;The official docs (&lt;a href="https://code.claude.com/docs/en/checkpointing" rel="noopener noreferrer"&gt;Checkpointing&lt;/a&gt;) frame checkpoints as "local undo" and Git as "permanent history." &lt;strong&gt;&lt;code&gt;/rewind&lt;/code&gt; does not rewrite Git history.&lt;/strong&gt; Anything you've &lt;code&gt;git commit&lt;/code&gt;-ed survives a rewind. Same idea for settings: put the thing you care about somewhere &lt;code&gt;/rewind&lt;/code&gt; can't reach, and it's safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to protect yourself
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code — keep every edit in Git.&lt;/strong&gt; Git is the layer &lt;code&gt;/rewind&lt;/code&gt; can't rewrite, so if your work is committed you can always recover it via &lt;code&gt;git reflog&lt;/code&gt; / &lt;code&gt;git log --all&lt;/code&gt;. A hook that auto-commits on each edit (like &lt;code&gt;auto-checkpoint.sh&lt;/code&gt;) keeps you in that state without thinking about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Settings — move provider vars out of settings.json.&lt;/strong&gt; Set them as real shell environment variables instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Git Bash: ~/.bashrc.  Windows: user env vars via setx.&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://your-provider/..."&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;strong&gt;delete those same keys from the &lt;code&gt;env&lt;/code&gt; block in &lt;code&gt;settings.json&lt;/code&gt;.&lt;/strong&gt; Once they're not in &lt;code&gt;settings.json&lt;/code&gt;, &lt;code&gt;/rewind&lt;/code&gt; has nothing to revert — Claude Code reads them from the actual environment, so the &lt;code&gt;env&lt;/code&gt; block is just a convenience. Your provider config now comes from the shell on every session, regardless of any rewind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After a rewind, verify the real file&lt;/strong&gt; if you're unsure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'ANTHROPIC_(BASE_URL|MODEL|AUTH_TOKEN)'&lt;/span&gt; ~/.claude/settings.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file contents are the evidence — not what the model says.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/rewind&lt;/code&gt; reverts code without confirmation, and reverts &lt;code&gt;settings.json&lt;/code&gt; too&lt;/li&gt;
&lt;li&gt;With a third-party provider, that can silently switch your billing to a different provider&lt;/li&gt;
&lt;li&gt;Protect code with &lt;code&gt;git commit&lt;/code&gt; (and an auto-commit hook) — Git is the un-rewindable layer&lt;/li&gt;
&lt;li&gt;Move provider vars to shell env and delete them from &lt;code&gt;settings.json&lt;/code&gt; — leave nothing to revert&lt;/li&gt;
&lt;li&gt;If unsure after a rewind, &lt;code&gt;grep&lt;/code&gt; the real &lt;code&gt;settings.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;These quiet, no-confirmation failures are the ones I keep designing around — I run Claude Code with real autonomy (800+ hours unattended) and keep the safety hooks I rely on in &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt; (&lt;code&gt;npx cc-safe-setup&lt;/code&gt;, MIT, runs locally, sends nothing out).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>devtools</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Claude Code said "file written" — but nothing ran: Opus 4.8's tool calls leaking as text (silent no-op)</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Mon, 29 Jun 2026 00:16:44 +0000</pubDate>
      <link>https://dev.to/yurukusa/claude-code-said-file-written-but-nothing-ran-opus-48s-tool-calls-leaking-as-text-silent-13cn</link>
      <guid>https://dev.to/yurukusa/claude-code-said-file-written-but-nothing-ran-opus-48s-tool-calls-leaking-as-text-silent-13cn</guid>
      <description>&lt;p&gt;Claude Code told you it wrote the file. It told you the push succeeded. You moved on. Hours later you check, and the file is empty and the remote never moved.&lt;/p&gt;

&lt;p&gt;This is a real failure mode on Opus 4.8 (1M context), and the dangerous part isn't that something got deleted — it's that &lt;strong&gt;nothing ran, but you were told it succeeded.&lt;/strong&gt; Here's what's happening and how to catch it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually going on
&lt;/h2&gt;

&lt;p&gt;When the model calls a tool (Bash, Edit, Write), it's supposed to emit a structured &lt;code&gt;tool_use&lt;/code&gt; block. The harness sees that block, runs the command, and feeds the real result back.&lt;/p&gt;

&lt;p&gt;Intermittently — usually deep into a long session — the model instead serializes the tool call as &lt;strong&gt;plain text&lt;/strong&gt;: the raw &lt;code&gt;&amp;lt;invoke ...&amp;gt;&lt;/code&gt; markup (with the &lt;code&gt;antml:&lt;/code&gt; prefix dropped) shows up as literal text in the reply. The harness never sees a &lt;code&gt;tool_use&lt;/code&gt; block, so &lt;strong&gt;the command never executes.&lt;/strong&gt; And the model frequently keeps going as if it had: "File updated", "Pushed", "Done."&lt;/p&gt;

&lt;p&gt;So this isn't only a stalled turn. It can be a &lt;em&gt;silent no-op&lt;/em&gt; where you're told something succeeded that never happened. Reported repeatedly this week: &lt;a href="https://github.com/anthropics/claude-code/issues/71812" rel="noopener noreferrer"&gt;#71812&lt;/a&gt;, &lt;a href="https://github.com/anthropics/claude-code/issues/72015" rel="noopener noreferrer"&gt;#72015&lt;/a&gt;, &lt;a href="https://github.com/anthropics/claude-code/issues/71952" rel="noopener noreferrer"&gt;#71952&lt;/a&gt; (which has the fullest transcript-level analysis).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it slips past you
&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;deleted&lt;/em&gt; file announces itself — an error, a missing file. This failure is the opposite: the work was &lt;strong&gt;never applied in the first place&lt;/strong&gt;, with no error and a stream of success-looking prose. You often find out much later, e.g. a &lt;code&gt;git ls-remote&lt;/code&gt; showing the branch never moved. A whole afternoon of "all done" can hide a back half where not a single write landed.&lt;/p&gt;

&lt;h2&gt;
  
  
  When it tends to hit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Long sessions, after one or more auto-compactions&lt;/li&gt;
&lt;li&gt;Non-ASCII-heavy sessions (&lt;a href="https://github.com/anthropics/claude-code/issues/72015" rel="noopener noreferrer"&gt;#72015&lt;/a&gt; points at this)&lt;/li&gt;
&lt;li&gt;Self-reinforcing: once it starts in a session, it tends to recur&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to catch it and stop the bleed
&lt;/h2&gt;

&lt;p&gt;Until it's fixed upstream:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Treat any raw &lt;code&gt;&amp;lt;invoke&amp;gt;&lt;/code&gt; / &lt;code&gt;antml:&lt;/code&gt;-style markup in the visible reply as "the tool did NOT run."&lt;/strong&gt; Don't act on the prose after it. Re-issue that step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. In a session that's started doing this, stop trusting success claims — verify ground truth before moving on:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git operations&lt;/span&gt;
git status
git ls-remote origin &amp;lt;branch&amp;gt;   &lt;span class="c"&gt;# did the push actually land?&lt;/span&gt;

&lt;span class="c"&gt;# file writes&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; path/to/file             &lt;span class="c"&gt;# mtime&lt;/span&gt;
&lt;span class="nb"&gt;stat &lt;/span&gt;path/to/file
&lt;span class="c"&gt;# or just open it and look&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"The model said so" is not evidence. The disk and git are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Cut sessions before they degrade.&lt;/strong&gt; Compacting/restarting rather than pushing one session for hours noticeably reduces recurrence. If you run with sub-agents / agent teams, test whether it reproduces with that off.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one piece of good news
&lt;/h2&gt;

&lt;p&gt;For the file-write case specifically: if the write never executed, &lt;strong&gt;your previous file contents are intact&lt;/strong&gt; — nothing was overwritten. The cost is the wasted turn, not lost work — &lt;em&gt;as long as you catch it before re-running a half-applied sequence.&lt;/em&gt; That's exactly why "verify before you continue" is the habit that matters most here.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This "success-shaped failure" shows up in more than one form — tool calls leaking as text, a verification step misreporting, a checkpoint silently reverting. I run Claude Code with real autonomy (800+ hours unattended) and keep the safety hooks I rely on in &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt; — &lt;code&gt;npx cc-safe-setup&lt;/code&gt;, MIT, runs locally, sends nothing out. Happy to compare notes if you've hit this one.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>opus</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Keep AGENTS.md and CLAUDE.md in sync: 5 user-side fixes (and where each quietly breaks)</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Sun, 28 Jun 2026 17:49:36 +0000</pubDate>
      <link>https://dev.to/yurukusa/keep-agentsmd-and-claudemd-in-sync-5-user-side-fixes-and-where-each-quietly-breaks-35p5</link>
      <guid>https://dev.to/yurukusa/keep-agentsmd-and-claudemd-in-sync-5-user-side-fixes-and-where-each-quietly-breaks-35p5</guid>
      <description>&lt;p&gt;If you use more than one AI coding assistant, you've probably hit this: Codex, Cursor, Amp, and Aider all read &lt;code&gt;AGENTS.md&lt;/code&gt;, but Claude Code reads only &lt;code&gt;CLAUDE.md&lt;/code&gt;. So you end up maintaining the same instructions in two files.&lt;/p&gt;

&lt;p&gt;The request to support &lt;code&gt;AGENTS.md&lt;/code&gt; is the single most-reacted open issue on the Claude Code repo — over 5,000 reactions, roughly 4x the second-place request — and it's still open. Until native support lands, here's how the user-side options actually compare, because each one breaks in a &lt;strong&gt;different&lt;/strong&gt; place.&lt;/p&gt;

&lt;h2&gt;
  
  
  The failure that actually costs you
&lt;/h2&gt;

&lt;p&gt;The upfront setup isn't the real problem. &lt;strong&gt;Silent drift&lt;/strong&gt; is.&lt;/p&gt;

&lt;p&gt;You update &lt;code&gt;AGENTS.md&lt;/code&gt;, forget &lt;code&gt;CLAUDE.md&lt;/code&gt; (or the other way around), and an instruction you were relying on — say a "don't touch production" guardrail — quietly stops applying for the tool reading the stale file. The mild annoyance of two files quietly turns into an incident.&lt;/p&gt;

&lt;p&gt;So the real goal isn't just "sync the files." It's "make a stale file fail &lt;strong&gt;loudly&lt;/strong&gt;."&lt;/p&gt;

&lt;h2&gt;
  
  
  5 options, and where each one breaks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. symlink&lt;/strong&gt; — &lt;code&gt;ln -s AGENTS.md CLAUDE.md&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;About 2 minutes for a solo dev.&lt;/li&gt;
&lt;li&gt;Breaks on Windows (needs admin / Developer Mode), and a WSL → Windows toolchain may not resolve the link.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. pre-commit hook&lt;/strong&gt; — auto-copy on commit&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great solo.&lt;/li&gt;
&lt;li&gt;The catch: it is &lt;strong&gt;not&lt;/strong&gt; reproduced by &lt;code&gt;git clone&lt;/code&gt;. Every teammate has to install it, so for a team you want a second layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. SessionStart hook&lt;/strong&gt; — compose at session start&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have Claude Code build &lt;code&gt;CLAUDE.md&lt;/code&gt; from &lt;code&gt;AGENTS.md&lt;/code&gt; when the session starts.&lt;/li&gt;
&lt;li&gt;Survives &lt;code&gt;clone&lt;/code&gt; (it lives in the repo) and needs no symlink.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. direnv&lt;/strong&gt; — swap via env vars&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nice if you already use direnv in the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. CI drift check&lt;/strong&gt; — don't sync at all&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Just fail CI when &lt;code&gt;AGENTS.md&lt;/code&gt; and &lt;code&gt;CLAUDE.md&lt;/code&gt; diverge.&lt;/li&gt;
&lt;li&gt;Safest for teams; it catches the "one got updated, the other didn't" bug directly — i.e. it's the one that makes a stale file fail loudly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pick by your setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Solo, one machine:&lt;/strong&gt; symlink, plus the CI drift check if you have CI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team:&lt;/strong&gt; SessionStart hook or CI drift check. Avoid a bare symlink or pre-commit hook as your &lt;em&gt;only&lt;/em&gt; layer — they don't survive &lt;code&gt;clone&lt;/code&gt; the way you'd expect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Several assistants in parallel:&lt;/strong&gt; SessionStart hook, so every tool reads a freshly composed file each session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whatever you choose for syncing, &lt;strong&gt;add the CI drift check on top.&lt;/strong&gt; That's the layer that converts a silent stale file into a loud, visible failure — which is the part that actually saves you.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is a stopgap
&lt;/h2&gt;

&lt;p&gt;Native &lt;code&gt;AGENTS.md&lt;/code&gt; support is obviously the right fix — that's why the issue has thousands of reactions. But these user-side options work today, and the CI drift check in particular is worth adding no matter which sync method you pick.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I maintain cc-safe-setup (install with &lt;code&gt;npx cc-safe-setup&lt;/code&gt;), a set of MIT-licensed safety hooks for Claude Code — the SessionStart sync approach above is one of them. Happy to compare notes if you're running multiple assistants on one repo.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want each of these methods in depth — with copy-paste &lt;code&gt;AGENTS.md&lt;/code&gt; / &lt;code&gt;CLAUDE.md&lt;/code&gt; templates and a tool-by-tool interop scorecard — I collected them in the &lt;a href="https://yurukusa.gumroad.com/l/swpeu" rel="noopener noreferrer"&gt;AGENTS.md × Claude Code Interop Handbook&lt;/a&gt; ($12, one-time). The fixes above are the free version; the handbook is the complete map.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>devtools</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I let Claude Code run autonomously for a month. "Productive" was a story my own logs didn't support</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Sun, 28 Jun 2026 02:36:36 +0000</pubDate>
      <link>https://dev.to/yurukusa/i-let-claude-code-run-autonomously-for-a-month-productive-was-a-story-my-own-logs-didnt-support-24i6</link>
      <guid>https://dev.to/yurukusa/i-let-claude-code-run-autonomously-for-a-month-productive-was-a-story-my-own-logs-didnt-support-24i6</guid>
      <description>&lt;p&gt;I ran Claude Code in a near-autonomous loop for weeks — wake it, let it work, check in once a day. Every session &lt;em&gt;looked&lt;/em&gt; productive: commits, files touched, tasks "done," long busy transcripts. Then I went back and counted what had actually reached a reader, a user, or a buyer. The number was much smaller than the motion suggested. The agent had been &lt;strong&gt;busy at the floor&lt;/strong&gt; — generating activity that reads as work but doesn't move anything outward.&lt;/p&gt;

&lt;p&gt;This isn't a "Claude is bad" post. It's the opposite: the model does what you point it at, and if your loop rewards &lt;em&gt;motion&lt;/em&gt;, you get motion. The fix is operator-side, and it's checkable against your own logs. Here's the part you can run today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Activity is not progress — and the logs will prove it
&lt;/h2&gt;

&lt;p&gt;The trap has a precise shape: an autonomous agent, left to define its own "progress," will count internal busywork — reorganizing notes, re-explaining its plan, re-reading files, "preparing" — as wins. None of it produces an outward outcome. Over a long run, the transcript fills up and the outward ledger stays nearly flat.&lt;/p&gt;

&lt;p&gt;You don't have to take my word for it. Claude Code writes every session to &lt;code&gt;~/.claude/projects/&amp;lt;project&amp;gt;/*.jsonl&lt;/code&gt;. Go count, per session: how many turns happened, versus how many produced something a reader/user/buyer could actually see (a publish, a shipped change, a sent reply). The ratio is usually sobering. Mine was.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two cheap defenses that change the loop
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. An outcome ledger where only outward events earn a line.&lt;/strong&gt; Keep a record (a flat file is enough) where the &lt;em&gt;only&lt;/em&gt; thing that registers as progress is an outward event with a link: published URL, shipped commit that reached users, a reply sent. Internal reorganizing is structurally unable to score. When "progress" can only mean "something left the building," the agent stops rewarding itself for motion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A gate that runs &lt;em&gt;before&lt;/em&gt; an action, not after.&lt;/strong&gt; Before starting any task, force two questions: &lt;strong&gt;who specifically benefits from this?&lt;/strong&gt; and &lt;strong&gt;which number moves within 14 days?&lt;/strong&gt; ("Myself" and "none" are failing answers.) Most floor-pointed work dies at this gate before it consumes a single token — which, in a long session, is also where the real money goes (the re-sent context is billed every turn and grows with conversation length, so a busy-but-pointless session is also an expensive one).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters more for autonomous runs than for chat
&lt;/h2&gt;

&lt;p&gt;In an interactive session you &lt;em&gt;are&lt;/em&gt; the gate — you feel the lack of progress and redirect. In an autonomous loop, nobody is watching turn by turn, so the busy-machine trap compounds silently until you check the ledger a day later and find motion without outcomes. The defenses above put the gate and the ledger &lt;em&gt;into the loop&lt;/em&gt; so it self-corrects instead of drifting.&lt;/p&gt;




&lt;p&gt;I wrote up the full version of this — seven mechanisms that make an autonomous agent &lt;em&gt;look&lt;/em&gt; productive while shipping little, each with something you can run against your own &lt;code&gt;~/.claude/projects/*.jsonl&lt;/code&gt; logs (the busy-machine trap, the outcome ledger, the pre-action gate, silent tool-result failures, the cost drain that grows with session length, carrying state across restarts, and protecting work a subsystem can silently wipe) — in a short book, &lt;strong&gt;&lt;a href="https://yurukusa.gumroad.com/l/iglmx" rel="noopener noreferrer"&gt;Autonomous Claude Ops&lt;/a&gt;&lt;/strong&gt; (7 chapters, on Gumroad). Every number in it is measured from real logs, with the verification script, or left out. Free hooks that wire some of these checks in: &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt; (&lt;code&gt;npx cc-safe-setup&lt;/code&gt;, MIT).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If your agent runs while you sleep, the dangerous failure isn't a crash — it's a month of busy transcripts that shipped nothing. Count the outward outcomes in your own logs before you trust the motion.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>An AI "migrated" my site — and left it publicly exposed to the world (#71882)</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Sun, 28 Jun 2026 02:04:34 +0000</pubDate>
      <link>https://dev.to/yurukusa/an-ai-migrated-my-site-and-left-it-publicly-exposed-to-the-world-71882-2pg0</link>
      <guid>https://dev.to/yurukusa/an-ai-migrated-my-site-and-left-it-publicly-exposed-to-the-world-71882-2pg0</guid>
      <description>&lt;p&gt;An AI coding agent was asked to &lt;em&gt;migrate&lt;/em&gt; a site to a new location. It reported "migration complete." The content did move. But &lt;strong&gt;none of the original access policies came across&lt;/strong&gt;, so a site that was meant to be private was left &lt;strong&gt;publicly readable by anyone&lt;/strong&gt; — and the only signal was that the reporter happened to go look later.&lt;br&gt;
This is a real, filed incident (&lt;a href="https://github.com/anthropics/claude-code/issues/71882" rel="noopener noreferrer"&gt;anthropics/claude-code #71882&lt;/a&gt;), not a hypothetical. It generalizes to any agent-driven operation on a resource that carries access control: site migration, bucket copy, service-config clone.&lt;br&gt;
The danger is the &lt;strong&gt;direction&lt;/strong&gt; of the failure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When &lt;em&gt;content&lt;/em&gt; migration fails, the page 404s. It fails &lt;strong&gt;loudly&lt;/strong&gt;, so you notice.&lt;/li&gt;
&lt;li&gt;When &lt;em&gt;access-control&lt;/em&gt; migration fails, the resource defaults to &lt;strong&gt;public&lt;/strong&gt;. And the run still reports "success." It fails &lt;strong&gt;silently, and in the unsafe direction.&lt;/strong&gt;
That asymmetry is the whole bug. The word "complete" masks the exposure. In the filed report, &lt;code&gt;errors: []&lt;/code&gt; — nothing surfaced. &lt;strong&gt;Surfacing nothing is itself part of the bug.&lt;/strong&gt;
Until the tool itself carries access policies across, you can defend operator-side. One idea underneath all three: &lt;strong&gt;never mistake the absence of a check for the result of a check.&lt;/strong&gt;
Provision the destination &lt;strong&gt;private / deny-all first&lt;/strong&gt;, move the content, and only then apply the &lt;strong&gt;verified&lt;/strong&gt; policy set. If a policy is dropped, the resource fails &lt;strong&gt;closed&lt;/strong&gt; (inaccessible — annoying) instead of &lt;strong&gt;open&lt;/strong&gt; (a breach). Never let the migration step double as "flip it public."
Before calling a migration of an access-controlled resource done, enumerate the effective policies / ACLs / visibility on &lt;strong&gt;both&lt;/strong&gt; source and target and confirm they &lt;strong&gt;match&lt;/strong&gt;. Not just that the content moved.
If public access wasn't intended, end the migration by mechanically checking that the public endpoint returns &lt;code&gt;401&lt;/code&gt;/&lt;code&gt;403&lt;/code&gt; (or that the bucket/site ACL is not &lt;code&gt;public&lt;/code&gt;). This turns an invisible failure into a loud one.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}'&lt;/span&gt; &lt;span class="s2"&gt;"https://example.com/should-be-private"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"401"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"403"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WARNING: possibly public — HTTP &lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The risk isn't "migration" specifically — it's the pattern of &lt;strong&gt;treating a check that never ran as the result of a check&lt;/strong&gt;. "deleted," "deployed," "uploaded," "migrated": for every irreversible, outward-facing verb, verify against the &lt;strong&gt;authoritative source&lt;/strong&gt; (the live endpoint, the bucket ACL, the remote state) rather than the narrated "success."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm "it isn't public" from &lt;code&gt;curl&lt;/code&gt;'s status code before believing it.&lt;/li&gt;
&lt;li&gt;Don't let "already migrated / already deployed" become a team's working assumption without the one-line check first.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - Put irreversible, outward operations behind a gate that stops them &lt;em&gt;before&lt;/em&gt; execution or verifies the real state &lt;em&gt;immediately after&lt;/em&gt;.
&lt;/h2&gt;

&lt;p&gt;This is exactly the kind of verified incident — detection → recovery → prevention, with the hook — that goes out monthly in the &lt;strong&gt;Agent Safety Brief&lt;/strong&gt;: the free edition emails you one incident a month (&lt;a href="https://yurukusa.substack.com" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;). But here is what makes it worth paying for: incidents like this one are not unique to Claude Code. The same failure shape has hit Cursor, Codex, Gemini CLI and Copilot, and a one-time, single-tool book cannot keep up with that. The &lt;a href="https://yurukusa.gumroad.com/l/xatlwf" rel="noopener noreferrer"&gt;$5/month&lt;/a&gt; membership is the cross-tool version: every failure that landed on the tracker that month, across every agentic coding tool, with paste-ready prevention for each (cancel anytime). A &lt;a href="https://yurukusa.gumroad.com/l/ymujuj" rel="noopener noreferrer"&gt;free sample issue&lt;/a&gt; is the complete public version of one paid month. Free hooks: &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;The AI's "complete" is not evidence that a check ran. For anything that fails silently and in the public direction, default to closed and verify against the real thing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>"My Claude Code conversation history showed up on another PC" — is it a leak? Where history lives, what syncs, and how to stop it</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Sun, 28 Jun 2026 01:52:16 +0000</pubDate>
      <link>https://dev.to/yurukusa/my-claude-code-conversation-history-showed-up-on-another-pc-is-it-a-leak-where-history-lives-3pdj</link>
      <guid>https://dev.to/yurukusa/my-claude-code-conversation-history-showed-up-on-another-pc-is-it-a-leak-where-history-lives-3pdj</guid>
      <description>&lt;p&gt;You're using Claude Code, you sign in to the same Anthropic account on a second machine, and suddenly the whole history you were building on the first PC — past conversations and all — appears on the other screen. Is your data leaking?&lt;/p&gt;

&lt;p&gt;This exact worry has been filed as a GitHub issue (&lt;a href="https://github.com/anthropics/claude-code/issues/71794" rel="noopener noreferrer"&gt;anthropics/claude-code #71794&lt;/a&gt;, with a &lt;code&gt;security&lt;/code&gt; label).&lt;/p&gt;

&lt;p&gt;The short version first: in the Claude Code world there are &lt;strong&gt;two separate histories&lt;/strong&gt;, and they sync completely differently. Separate them and most of what you're seeing is explained — whether it's a real bug, expected behavior, or a backup/sync tool of your own doing the copying. And here's the line that matters most, the one I keep coming back to in my incident work: &lt;strong&gt;the first surprise is rarely the expensive part — the panicked next move is.&lt;/strong&gt; If you assume "leak" and wipe your history, then later find out it was expected behavior (or your own sync folder), you've destroyed the very thing you needed to diagnose it. Separate first, then act.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two histories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The terminal CLI's local, on-this-machine history
&lt;/h3&gt;

&lt;p&gt;The conversation history from running &lt;code&gt;claude&lt;/code&gt; in a terminal is stored on that PC's disk, in known locations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per-project conversations: &lt;code&gt;~/.claude/projects/&amp;lt;project-hash&amp;gt;/*.jsonl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The cross-project index: &lt;code&gt;~/.claude/history.jsonl&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key point: &lt;strong&gt;the CLI itself does not upload these files to the cloud or sync them to another machine.&lt;/strong&gt; A first-party cloud sync isn't implemented yet — it's an open feature request (&lt;a href="https://github.com/anthropics/claude-code/issues/7805" rel="noopener noreferrer"&gt;#7805&lt;/a&gt;). That's exactly why the community builds its own &lt;code&gt;rsync&lt;/code&gt;/&lt;code&gt;git&lt;/code&gt; sync tools. So a pure terminal &lt;code&gt;claude&lt;/code&gt; session, left alone, should stay on that one machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The account-bound, cloud side
&lt;/h3&gt;

&lt;p&gt;These surfaces, by contrast, store conversations server-side per account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;claude.ai (the web app)&lt;/li&gt;
&lt;li&gt;Desktop app / Cowork&lt;/li&gt;
&lt;li&gt;Remote Control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are tied to your Anthropic account, so &lt;strong&gt;showing up on every signed-in device is by design.&lt;/strong&gt; A conversation created here appearing on another PC is not abnormal.&lt;/p&gt;

&lt;p&gt;There's also &lt;strong&gt;Memory&lt;/strong&gt;, default-on for all users since March 2026, which remembers preferences, in-progress projects, and working style across conversations and devices. But that's a summarized memory, not the full text of your conversations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check which one you're hitting — without opening the UI
&lt;/h2&gt;

&lt;p&gt;When history "appears," the fastest, most reliable move is to look at the filesystem directly on the machine where it showed up (call it Device B), before opening any UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; ~/.claude/projects/
&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; ~/.claude/history.jsonl 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the other machine's conversations &lt;strong&gt;physically exist&lt;/strong&gt; as &lt;code&gt;.jsonl&lt;/code&gt; files on Device B's disk — something is copying files. That's &lt;strong&gt;your own environment&lt;/strong&gt;, not Claude Code (see below).&lt;/li&gt;
&lt;li&gt;If the files are &lt;strong&gt;not&lt;/strong&gt; on disk but the UI shows them — that's not the CLI's local history; it's a cloud surface rendering the account's server-side history. &lt;strong&gt;By design&lt;/strong&gt;, not a leak.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That one check separates "real bug," "by design," and "your own sync."&lt;/p&gt;

&lt;h2&gt;
  
  
  The most common real culprit — &lt;code&gt;~/.claude&lt;/code&gt; lives under a sync folder
&lt;/h2&gt;

&lt;p&gt;Most "the CLI synced!" cases are because &lt;code&gt;~/.claude&lt;/code&gt; itself is inside a cloud-sync target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Is ~/.claude a real dir, or a link pointing into a sync folder?&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-ld&lt;/span&gt; ~/.claude
&lt;span class="nb"&gt;readlink&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;~/.claude&lt;/code&gt; is under OneDrive / iCloud Drive / Dropbox (or is a symlink into one), then Claude Code did nothing — a sync tool is copying the files to your other machine behind the scenes. Windows OneDrive pulling in the whole user folder is an especially common shape. The same goes for &lt;code&gt;~/.claude&lt;/code&gt; being inside a dotfiles &lt;code&gt;git&lt;/code&gt; repo, or a backup tool's target.&lt;/p&gt;

&lt;p&gt;This is also where exposure meets credential exposure: conversation transcripts can contain &lt;strong&gt;secrets and tokens stored verbatim&lt;/strong&gt;. If &lt;code&gt;~/.claude&lt;/code&gt; is flowing to another machine — or a shared cloud folder — that's not just history exposure, it's &lt;strong&gt;credential exposure&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stopping the exposure / separating devices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Move &lt;code&gt;~/.claude&lt;/code&gt; out of sync&lt;/strong&gt;: if &lt;code&gt;readlink&lt;/code&gt; shows it under a sync folder, move the real directory somewhere outside sync and add &lt;code&gt;~/.claude&lt;/code&gt; to the tool's exclude list. This is the single most effective cut for "CLI history being shipped without my asking."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turn Memory off&lt;/strong&gt;: claude.ai → Settings → Memory toggle off; subsequent conversations start fresh.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opt out of training&lt;/strong&gt;: Settings → Privacy, turn off using conversations for future model training.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't retain temporarily&lt;/strong&gt;: claude.ai Incognito (ghost icon) conversations aren't used for training even if your account allows it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate per device&lt;/strong&gt;: keep work on the terminal CLI, don't route the same case through Web / Desktop / Remote, and confirm &lt;code&gt;~/.claude&lt;/code&gt; is outside any sync folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Honest limits
&lt;/h2&gt;

&lt;p&gt;What Anthropic does server-side isn't visible from your machine. If a pure terminal CLI session truly full-text-synced to another device with no sync tool, no backup, and no shared storage involved, that would be a genuine bug worthy of the &lt;code&gt;security&lt;/code&gt; label. In that case, report it with: which client you used on each device (terminal &lt;code&gt;claude&lt;/code&gt;, Desktop/Cowork, or claude.ai web), and whether the &lt;code&gt;.jsonl&lt;/code&gt; files physically exist on Device B's disk. That turns a vague "it leaked" into a fast root-cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one line
&lt;/h2&gt;

&lt;p&gt;If it feels like a leak, &lt;strong&gt;don't wipe before you check&lt;/strong&gt; — run &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;readlink&lt;/code&gt; and see what's actually happening on your machine right now. Data incidents get worse when you act on assumption. Confirming facts one at a time is, in the end, the fastest and safest path.&lt;/p&gt;




&lt;p&gt;This is exactly the kind of verified incident — detection → recovery → prevention — that goes out monthly in the &lt;strong&gt;Agent Safety Brief&lt;/strong&gt;: the free edition emails you one incident a month (&lt;a href="https://yurukusa.substack.com" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;). But here is what makes it worth paying for: incidents like this one are not unique to Claude Code. The same failure shape has hit Cursor, Codex, Gemini CLI and Copilot, and a one-time, single-tool book cannot keep up with that. The &lt;a href="https://yurukusa.gumroad.com/l/xatlwf" rel="noopener noreferrer"&gt;$5/month&lt;/a&gt; membership is the cross-tool version: every failure that landed on the tracker that month, across every agentic coding tool, with paste-ready prevention for each (cancel anytime). A &lt;a href="https://yurukusa.gumroad.com/l/ymujuj" rel="noopener noreferrer"&gt;free sample issue&lt;/a&gt; is the complete public version of one paid month. Free hooks: &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"It showed up on another device" is usually one of two known histories, or your own sync folder — not a server-side leak. Check the disk before you delete.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>Two unrelated Claude Code Opus 4.8 failures hit the same week: token burn and fabricated tool results</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Fri, 12 Jun 2026 14:41:22 +0000</pubDate>
      <link>https://dev.to/yurukusa/two-unrelated-claude-code-opus-48-failures-hit-the-same-week-token-burn-and-fabricated-tool-31hi</link>
      <guid>https://dev.to/yurukusa/two-unrelated-claude-code-opus-48-failures-hit-the-same-week-token-burn-and-fabricated-tool-31hi</guid>
      <description>&lt;p&gt;In late May 2026, operators running Claude Code on Opus 4.8 (&lt;code&gt;claude-opus-4-8&lt;/code&gt;) filed two structurally different failures within the same few days. One burns money. The other corrupts correctness.&lt;/p&gt;

&lt;p&gt;I run Claude Code autonomously, around the clock, so neither of these was abstract for me. And as of &lt;strong&gt;June 12&lt;/strong&gt;, both are still being reported on the latest builds — with no fix announcement I could find. The billing change landing on &lt;strong&gt;June 15&lt;/strong&gt; makes the cost one especially worth understanding now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure 1: 46,000 tokens for a trivial task
&lt;/h2&gt;

&lt;p&gt;The first failure hits your bill directly.&lt;/p&gt;

&lt;p&gt;In the anchor report, a routine &lt;em&gt;rename-impact scan&lt;/em&gt; — a boring "where is this symbol used" task — made Opus 4.8 emit &lt;strong&gt;46,433 output tokens after 22 minutes and 43 seconds of thinking&lt;/strong&gt;. The effort setting was &lt;code&gt;medium&lt;/code&gt;. This wasn't a crash or a retry loop; the turn completed normally (&lt;code&gt;stop_reason: end_turn&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The same prompt on Opus 4.6 or 4.7 reportedly produced &lt;strong&gt;2,000–3,000 tokens with comparable quality&lt;/strong&gt;. So the output ballooned by roughly 10–40×.&lt;/p&gt;

&lt;p&gt;The reporter's framing was simply: &lt;em&gt;"session limits maxing out on their own, without any interaction from the user."&lt;/em&gt; A trivial task, quietly over-thinking itself into your quota.&lt;/p&gt;

&lt;p&gt;This didn't stay contained to late May. Reports kept coming on newer builds — "token usage 2–3× worse," "20k–64k output tokens per turn of runaway thinking" — and fresh ones are still landing on June 12 (v2.1.173). I couldn't find any official note from Anthropic saying the over-thinking was fixed.&lt;/p&gt;

&lt;p&gt;Relevant issues: &lt;code&gt;anthropics/claude-code#64153&lt;/code&gt;, &lt;code&gt;#64152&lt;/code&gt;, &lt;code&gt;#64143&lt;/code&gt;, &lt;code&gt;#64102&lt;/code&gt;, and newer &lt;code&gt;#64961&lt;/code&gt;, &lt;code&gt;#66711&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure 2: tool results fabricated before the tool returns
&lt;/h2&gt;

&lt;p&gt;The second failure is unrelated in nature — it doesn't cost money, it corrupts your output.&lt;/p&gt;

&lt;p&gt;Claude Code calls tools (read file, search, run command), then answers based on what they return. On Opus 4.8, there were reports of the model &lt;strong&gt;reporting a concrete result before the tool call had returned anything&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The clearest example: on a flight-price lookup, the model answered "&lt;strong&gt;$891 pp / $1,782 for two&lt;/strong&gt;" &lt;em&gt;before&lt;/em&gt; the search came back. The real value, once the tool actually returned, was about &lt;strong&gt;$645 pp&lt;/strong&gt;. It had reported a roughly 2× price that did not exist yet.&lt;/p&gt;

&lt;p&gt;Worse: there were reports of the model recognizing the habit, explicitly promising "I won't do that again," and then doing exactly the same thing in the very next turn. Verbal correction doesn't hold it — it's structural.&lt;/p&gt;

&lt;p&gt;This one is also still alive. On June 10, an operator inspected raw JSONL and verified a &lt;em&gt;completely phantom&lt;/em&gt; tool call — the model claimed a tool ran, but &lt;strong&gt;no &lt;code&gt;tool_use&lt;/code&gt; block existed in the transcript at all&lt;/strong&gt;. A June 12 report (v2.1.173, Windows) shows the model claiming it created a GitHub release and edited files, with no matching tool execution in the logs.&lt;/p&gt;

&lt;p&gt;Relevant issues: &lt;code&gt;anthropics/claude-code#64065&lt;/code&gt;, &lt;code&gt;#64048&lt;/code&gt;, &lt;code&gt;#64076&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why they belong in the same post
&lt;/h2&gt;

&lt;p&gt;These two symptoms are completely different on the surface — one is cost, one is correctness — but they surfaced in the same window, on the same model. One side &lt;em&gt;over-thinks&lt;/em&gt;, the other side &lt;em&gt;runs ahead of its own tools&lt;/em&gt;. Both look like the model failing to calmly walk through its steps. They may well be two faces of the same regression.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can do today
&lt;/h2&gt;

&lt;p&gt;The root cause is on the model side; you can't fully fix it. But you can avoid the damage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Roll the model back.&lt;/strong&gt; Both failures showed up on Opus 4.8 specifically. Opus 4.7 (&lt;code&gt;claude-opus-4-7&lt;/code&gt;) is &lt;strong&gt;not deprecated and is still selectable&lt;/strong&gt;. If your reason for 4.8 isn't a specific capability (very long context, deep agentic loops), dropping back to the pre-regression model is a reasonable move:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;claude-opus-4-7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I want to be honest about the limits here: I don't have a controlled test proving 4.7 &lt;em&gt;guarantees&lt;/em&gt; both failures disappear. Treat it as "this is a 4.8 regression, so step back to the version before it," not a certified cure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make runaway harder.&lt;/strong&gt; What people actually report helping: running tools &lt;strong&gt;one per turn&lt;/strong&gt; (sequential, not batched), and stepping &lt;code&gt;effort&lt;/code&gt; &lt;strong&gt;down&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measure your own burn.&lt;/strong&gt; Don't argue from vibes — look at the number. Pull the median output tokens from your recent transcripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s1"&gt;'map(.message.usage.output_tokens // 0) | sort | .[length/2]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ~/.claude/projects/&lt;span class="k"&gt;**&lt;/span&gt;/recent.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the median for ordinary work is north of ~10k tokens, Failure 1 is probably happening to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is urgent: the June 15 billing split
&lt;/h2&gt;

&lt;p&gt;On June 15, Anthropic splits the billing pools, and this part is easy to get wrong, so let me separate it cleanly.&lt;/p&gt;

&lt;p&gt;Until now, interactive Claude Code and programmatic Claude Code shared one subscription budget. From June 15:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interactive use&lt;/strong&gt; (you typing into the terminal / IDE / app) stays on your subscription budget. No per-token dollar charge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programmatic use&lt;/strong&gt; (Agent SDK, &lt;code&gt;claude -p&lt;/code&gt;, GitHub Actions) moves to a &lt;strong&gt;separate pool billed at full API rates&lt;/strong&gt;, no rollover, stops when depleted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So Failure 1 — the token burn — bites hardest for anyone running &lt;strong&gt;Opus 4.8 in automation&lt;/strong&gt;: wasted tokens convert straight into dollars.&lt;/p&gt;

&lt;p&gt;If you only use it interactively, you're not immune either: the burn eats your subscription budget faster, which shows up as the "I did light work and got locked out for the day" quota-exhaustion pain.&lt;/p&gt;

&lt;p&gt;Either way, the few days before June 15 are a good moment to measure how much Opus 4.8 is actually costing you, and roll back to 4.7 if it's bleeding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Late May, Opus 4.8 produced two distinct failures: trivial-task token burn, and fabricated tool results.&lt;/li&gt;
&lt;li&gt;Both are still being reported on the latest June 12 builds, with no fix announcement.&lt;/li&gt;
&lt;li&gt;Operator-side levers: roll back to Opus 4.7 / one tool per turn / lower effort / measure your own median output tokens.&lt;/li&gt;
&lt;li&gt;The June 15 billing split turns the burn into real dollars for automated use, and faster quota exhaustion for interactive use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I caught this on my own setup, I dropped my working model back to 4.7 and watched the median output tokens fall back to normal. The lesson that stuck: a newer model isn't automatically a better one.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I run an AI coding agent autonomously and keep a free 15-line self-check (&lt;code&gt;verify.py&lt;/code&gt;) plus sample material in a companion repo: yurukusa/autonomous-claude-ops. The safety hooks I use to catch silent failures like these are open source in &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt;. Both are free — no signup.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
    </item>
    <item>
      <title>I ran an AI coding agent autonomously for a month. A 15-line script showed me it produced almost nothing.</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Thu, 11 Jun 2026 10:43:55 +0000</pubDate>
      <link>https://dev.to/yurukusa/i-ran-an-ai-coding-agent-autonomously-for-a-month-a-15-line-script-showed-me-it-produced-almost-1g0h</link>
      <guid>https://dev.to/yurukusa/i-ran-an-ai-coding-agent-autonomously-for-a-month-a-15-line-script-showed-me-it-produced-almost-1g0h</guid>
      <description>&lt;p&gt;I spent a month making sure my autonomous AI coding agent would never sit idle. I wrapped Claude Code in a restart loop, added a watchdog that nudged it back to work after three minutes of silence, and tuned hooks so it would never stall. It worked. The machine almost never idled.&lt;/p&gt;

&lt;p&gt;Then one evening I ran a fifteen-line script over every session log on disk, and it reframed everything I thought I knew about running an agent on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number I was watching
&lt;/h2&gt;

&lt;p&gt;The fear when you first leave an agent running unattended is obvious: &lt;em&gt;what if it just stops?&lt;/em&gt; What if it sits there burning a subscription, waiting for a human who isn't coming? So that is the failure mode I engineered against, for weeks.&lt;/p&gt;

&lt;p&gt;By that metric, the month was a triumph. Here is the raw shape of the work, straight from &lt;code&gt;~/.claude/projects/*/*.jsonl&lt;/code&gt;, with no rounding in my favor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;295 sessions&lt;/strong&gt; retained locally, spanning about 32 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Median 488 assistant responses per session&lt;/strong&gt; (an "assistant response" = one real turn: call a tool, read the result, decide, call the next)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;85% of sessions did more than 100 responses&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sessions that did literally nothing: 6. Two percent.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The machine was not idle. The machine was a firehose. I had spent a month defending against a failure mode that happened two percent of the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number that wasn't there
&lt;/h2&gt;

&lt;p&gt;Now the other side of the ledger. Same month, same machine — everything that actually left the building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;47 product folders&lt;/strong&gt; created on disk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;36 finished drafts&lt;/strong&gt; sitting unpublished&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 sales&lt;/strong&gt; in the outcome ledger I'd started keeping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Forty-seven product folders. Thirty-six drafts that were &lt;em&gt;done&lt;/em&gt; — written, edited, ready — and never shipped. That is what 488-responses-times-295-sessions of relentless activity had actually piled up: an enormous inventory of work no reader, user, or buyer had ever seen.&lt;/p&gt;

&lt;p&gt;The firehose was pointed at the floor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it on your own logs
&lt;/h2&gt;

&lt;p&gt;This isn't a vibe. It's two minutes of counting. Here is the whole script — it's read-only, it writes nothing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;statistics&lt;/span&gt;

&lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expanduser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;~/.claude/projects/*/*.jsonl&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistant&lt;/span&gt;&lt;span class="sh"&gt;"'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sessions          : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;median responses  : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;statistics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sessions over 100 : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;did nothing       : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your median is in the hundreds and your &lt;em&gt;outward&lt;/em&gt; output — things published, shipped, sold — is near zero, you are where I was. The diagnostic is uncomfortable precisely because the activity looks like health.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a tireless agent makes this worse, not better
&lt;/h2&gt;

&lt;p&gt;The failure mode of autonomous AI operation is &lt;strong&gt;not idleness&lt;/strong&gt;. It's &lt;strong&gt;motion that never reaches anyone&lt;/strong&gt; — and a tireless agent generates that comforting motion &lt;em&gt;faster&lt;/em&gt; than a lazy one would. Every loop produces a plausible next action. Refactor this. Draft that. Audit the other thing. None of it is wrong, exactly. It just never crosses the line from &lt;em&gt;activity&lt;/em&gt; to &lt;em&gt;outcome&lt;/em&gt;, and the firehose volume hides the gap behind a wall of green checkmarks.&lt;/p&gt;

&lt;p&gt;Three things moved the needle for me, and none of them were "work harder":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;An outcome ledger.&lt;/strong&gt; Redefine "progress" so that busywork structurally cannot count as a win — only a reader/user/buyer seeing something does. If a session can't name what reached a person, it didn't progress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A gate before the action.&lt;/strong&gt; Two questions asked &lt;em&gt;before&lt;/em&gt; starting any task — who is helped, and which number it moves in 14 days — that kill floor-pointed work before it eats a single token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A session-boundary rule.&lt;/strong&gt; One handoff discipline so every restart doesn't re-derive what the last session already settled (a huge silent drain when you run in loops).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  If you want to dig in
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The script above, a richer read-only audit, and the full free first chapter are in the companion repo: &lt;strong&gt;autonomous-claude-ops&lt;/strong&gt;. Run the audit, read the diagnosis, decide for yourself.&lt;/li&gt;
&lt;li&gt;If you operate Claude Code and want the broader free safety tooling (hooks that catch destructive operations, token drain, silent failures), that lives here: &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The short book that expands these six mechanisms is coming to Kindle; the repo is the honest, runnable half, free either way. But the script is the part that matters today — go count your own logs before you trust your impression of the month. Mine was wrong by a wide margin.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>My AI agent answered 488 times a session. It shipped nothing.</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Wed, 10 Jun 2026 19:31:54 +0000</pubDate>
      <link>https://dev.to/yurukusa/my-ai-agent-answered-488-times-a-session-it-shipped-nothing-3a9j</link>
      <guid>https://dev.to/yurukusa/my-ai-agent-answered-488-times-a-session-it-shipped-nothing-3a9j</guid>
      <description>&lt;p&gt;When you first leave an AI coding agent running on its own, the fear is obvious: &lt;em&gt;what if it just stops?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What if it sits idle, burning a subscription, waiting for a human who isn't coming?&lt;/p&gt;

&lt;p&gt;So that is what I built against. I wrapped Claude Code in a restart loop. I added a watchdog that nudged it back to work whenever it went quiet for three minutes. I tuned hooks to keep it from stalling. For about a month, almost all of my effort went into one goal: &lt;strong&gt;never let the machine idle.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It worked. The machine almost never idled.&lt;/p&gt;

&lt;p&gt;Then one evening I did the thing I should have done on day one. I stopped trusting my impression of how the month had gone, and I counted.&lt;/p&gt;

&lt;h2&gt;
  
  
  A month of "productive" autonomy, straight from the logs
&lt;/h2&gt;

&lt;p&gt;Every session Claude Code runs leaves a transcript on disk under &lt;code&gt;~/.claude/projects/*/*.jsonl&lt;/code&gt;. I ran a fifteen-line script over all of mine. No rounding in my favor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;295 sessions&lt;/strong&gt;, spanning about 32 days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Median 488 assistant responses per session.&lt;/strong&gt; (An "assistant response" is one real turn of work: call a tool, read the result, decide, call the next.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;252 of 295 sessions — 85% — produced more than 100 responses.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sessions that did literally nothing — zero responses: 6. Two percent.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sit with that median. Four hundred and eighty-eight turns of work in the middle session. By the only metric I had been watching — &lt;em&gt;is it working?&lt;/em&gt; — this was a triumph. The machine wasn't idle. The machine was a firehose.&lt;/p&gt;

&lt;p&gt;I had spent a month defending against a failure mode that happened two percent of the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other side of the ledger
&lt;/h2&gt;

&lt;p&gt;Same month, same machine. Here is everything that actually left the building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;47 product folders&lt;/strong&gt; created under &lt;code&gt;~/products/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;36 finished drafts&lt;/strong&gt; — written, edited, ready — sitting unpublished.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;¥6,144&lt;/strong&gt; in cumulative revenue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 sales&lt;/strong&gt; recorded in the outcome ledger I had started keeping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Forty-seven product folders. Thirty-six drafts that were &lt;em&gt;done&lt;/em&gt; and never shipped. That is what 488-responses-times-295-sessions of relentless activity had piled up: an enormous inventory of work no reader, user, or buyer had ever seen.&lt;/p&gt;

&lt;p&gt;The firehose was pointed at the floor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two kinds of numbers that feel identical from the inside
&lt;/h2&gt;

&lt;p&gt;Here is the trap, stated plainly. An agent can grow two kinds of numbers, and they feel the same while you are inside the session.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;first kind measures motion&lt;/strong&gt;: responses, tool calls, commits, files touched, drafts written. These are cheap. An agent that never idles grows them without limit, and every increment &lt;em&gt;feels&lt;/em&gt; like progress. The session was busy. The commit count went up. Surely something happened.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;second kind measures outward value&lt;/strong&gt;: things published, things sold, things a real person reacted to. These are expensive — and here is the cruel part — &lt;em&gt;an agent cannot grow them by working harder.&lt;/em&gt; Publishing requires a decision to expose work to judgment. Selling requires someone on the other side. No amount of internal motion crosses that gap on its own.&lt;/p&gt;

&lt;p&gt;An autonomous agent optimizes whatever you let it count as progress. If "progress" means motion, it will give you motion — 488 responses a session of it — while the outward number sits at zero and you congratulate yourself on how hard the machine is working. The very thing I built to prevent idleness made the trap &lt;em&gt;worse&lt;/em&gt;, because a tireless machine generates the comforting motion faster than a lazy one would.&lt;/p&gt;

&lt;p&gt;This isn't a Claude Code problem. It's a problem with what you tell &lt;em&gt;any&lt;/em&gt; autonomous worker to count. But agents make it acute, because they remove the natural friction — boredom, fatigue, the human pause before busywork — that used to cap how much motion you could mistake for progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Count it on your own machine
&lt;/h2&gt;

&lt;p&gt;Don't take my 488 on faith. If you run Claude Code, the same claim is checkable against your own logs. This only reads; it changes nothing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 - &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;PY&lt;/span&gt;&lt;span class="sh"&gt;'
import glob, os, statistics
counts = []
for f in glob.glob(os.path.expanduser('~/.claude/projects/*/*.jsonl')):
    a = sum(1 for line in open(f) if '"type":"assistant"' in line)
    counts.append(a)
if counts:
    counts.sort()
    print(f"sessions:            {len(counts)}")
    print(f"median responses:    {statistics.median(counts):.0f}")
    print(f"over 100 responses:  {sum(1 for c in counts if c &amp;gt; 100)}")
    print(f"zero-response (idle): {sum(1 for c in counts if c == 0)}")
&lt;/span&gt;&lt;span class="no"&gt;PY
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now hold that median next to a number only you can produce: &lt;strong&gt;how many things did this machine actually ship to a real person in the same period?&lt;/strong&gt; Published posts, sales, replies that helped someone. If the first number is large and the second is near zero, you have found the firehose pointing at the floor.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix is a different scoreboard, not a faster machine
&lt;/h2&gt;

&lt;p&gt;The way out is not more hooks or a tighter restart loop. It is to make the agent count the &lt;em&gt;expensive&lt;/em&gt; number. The single change that moved mine: an &lt;strong&gt;outcome ledger&lt;/strong&gt; — one append-only file where the only events that count are &lt;code&gt;publish&lt;/code&gt;, &lt;code&gt;sell&lt;/code&gt;, &lt;code&gt;release&lt;/code&gt;, and &lt;code&gt;real reaction&lt;/code&gt;. Tool calls don't go in it. Commits don't go in it. Drafts don't go in it. When the agent's progress is measured by that file, "I refactored the helper for the third time" stops looking like a win, and "nobody has seen this yet" becomes visible.&lt;/p&gt;

&lt;p&gt;I wrote up the full version of this — the ledger, the gate that runs before risky actions, the silent-failure detection, and surviving the context-window boundary — as a short, honest book built entirely on real logs. The &lt;strong&gt;companion repo is free and runnable&lt;/strong&gt; (the counter above, an expanded &lt;code&gt;verify.py&lt;/code&gt;, and the first chapter in full):&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;autonomous-claude-ops&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you run an agent unattended — or you're about to — count your two numbers first. The motion one will flatter you. The outward one is the only one your users ever see.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Found 39 Days Where I 'Worked' But Didn't. Here's What That Data Looks Like.</title>
      <dc:creator>Yurukusa</dc:creator>
      <pubDate>Mon, 13 Apr 2026 03:00:02 +0000</pubDate>
      <link>https://dev.to/yurukusa/i-found-39-days-where-i-worked-but-didnt-heres-what-that-data-looks-like-212j</link>
      <guid>https://dev.to/yurukusa/i-found-39-days-where-i-worked-but-didnt-heres-what-that-data-looks-like-212j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (June 2026):&lt;/strong&gt; I later re-ran this with a sharper method — counting &lt;em&gt;assistant responses per session&lt;/em&gt; instead of activity per day. The result corrected me: the agent was almost never idle (only &lt;strong&gt;2%&lt;/strong&gt; of sessions did nothing). The real failure mode wasn't ghost days at all — it was busy sessions, a median of &lt;strong&gt;488 responses each&lt;/strong&gt;, that shipped nothing to a single reader. I wrote up the corrected and fuller analysis here: &lt;a href="https://dev.to/yurukusa/my-ai-agent-answered-488-times-a-session-it-shipped-nothing-3a9j"&gt;&lt;strong&gt;My AI agent answered 488 times a session. It shipped nothing.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;There's a type of day that doesn't show up in your commit history.&lt;/p&gt;

&lt;p&gt;You opened Claude Code. Maybe you ran a command or two. Maybe you read some output. But nothing shipped. Nothing moved. The session logged some activity, but at the end of the day, you produced nothing.&lt;/p&gt;

&lt;p&gt;I call these Ghost Days.&lt;/p&gt;

&lt;p&gt;I have 39 of them. Out of 60 days.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a Ghost Day actually is
&lt;/h2&gt;

&lt;p&gt;A Ghost Day is a day where Claude Code activity is below a meaningful threshold — where you clearly had the tool open and running, but the session produced no real output.&lt;/p&gt;

&lt;p&gt;The definition I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fewer than 10 tool calls&lt;/strong&gt; in the day's sessions (noise level)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AND&lt;/strong&gt; fewer than 3 file modifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OR&lt;/strong&gt; total active session time under 5 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second condition is the key one. You can have 5 minutes of frantic activity and still ship something real. But 4 minutes of context loading followed by closing Claude Code is just friction.&lt;/p&gt;




&lt;h2&gt;
  
  
  The data from my 60 days
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Total days in range&lt;/strong&gt;: 60&lt;br&gt;
&lt;strong&gt;Ghost Days&lt;/strong&gt;: 39 (65%)&lt;br&gt;
&lt;strong&gt;Active Days&lt;/strong&gt;: 21 (35%)&lt;/p&gt;

&lt;p&gt;Wait. I had Ghost Days on 65% of days?&lt;/p&gt;

&lt;p&gt;That didn't match my mental model at all. I thought I'd been working consistently. The numbers said otherwise.&lt;/p&gt;

&lt;p&gt;Let me break it down further.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ghost Days by day of week:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monday: 7/8 days (88% ghost rate)&lt;/li&gt;
&lt;li&gt;Saturday: 6/8 days (75%)&lt;/li&gt;
&lt;li&gt;Tuesday: 5/8 days (63%)&lt;/li&gt;
&lt;li&gt;Wednesday: 4/8 days (50%)&lt;/li&gt;
&lt;li&gt;Thursday: 4/8 days (50%)&lt;/li&gt;
&lt;li&gt;Friday: 4/8 days (50%)&lt;/li&gt;
&lt;li&gt;Sunday: 9/12 days (75%)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Monday had a 88% ghost rate. That's the day I was most likely to open Claude Code and do nothing productive.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;I'm paying $200/month for Claude Code. That's $6.67/day.&lt;/p&gt;

&lt;p&gt;On Ghost Days, I paid $6.67 for approximately zero output.&lt;/p&gt;

&lt;p&gt;Over 39 Ghost Days, that's $260 spent on sessions where nothing happened.&lt;/p&gt;

&lt;p&gt;That's 65% of my subscription cost going to days where I either couldn't get started, got interrupted, or just... didn't engage meaningfully.&lt;/p&gt;

&lt;p&gt;The non-Ghost Days had to justify the full $400 with 21 days of actual work. Some did. Most produced something. But the distribution was brutal.&lt;/p&gt;


&lt;h2&gt;
  
  
  What causes Ghost Days
&lt;/h2&gt;

&lt;p&gt;Looking at the pattern, I can identify three main causes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Context-loading sessions&lt;/strong&gt;&lt;br&gt;
I'd open Claude Code to check something — "where did I leave off?" — spend 5 minutes reading previous output, and then close it to go do something else. This logs as activity but produces nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Blocked days&lt;/strong&gt;&lt;br&gt;
Days where I hit a problem early (npm rate limit, CDP auth failure, etc.) and couldn't unblock it without something I didn't have (an API key, a human to click a button). The whole day became a Ghost Day because the first session failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Cognitive overhead&lt;/strong&gt;&lt;br&gt;
Some days I'd start sessions, read the output, feel uncertain about what to do next, and close without committing to anything. Analysis paralysis, but logged as Claude Code activity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Legitimate rest&lt;/strong&gt;&lt;br&gt;
Some Ghost Days were intentional non-work days. They look identical to the other Ghost Days in the data. The tool can't tell the difference.&lt;/p&gt;


&lt;h2&gt;
  
  
  What I changed
&lt;/h2&gt;

&lt;p&gt;Knowing the Ghost Day pattern changed two things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, I started front-loading.&lt;/strong&gt; If my Monday has an 88% ghost rate, I needed to put the most important work earlier in the week — Wednesday through Friday, when I'm most likely to actually execute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second, I built a blockers file.&lt;/strong&gt; Instead of closing Claude Code when blocked, I now write the blocker to &lt;code&gt;~/ops/pending_for_human.md&lt;/code&gt; and immediately pivot to something else. This converts a potential Ghost Day into a partial ghost day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I didn't change&lt;/strong&gt;: my subscription. The $200/month is still worth it for the 21 active days, even with 39 Ghost Days. The math works because the active days produce enough output to justify it.&lt;/p&gt;


&lt;h2&gt;
  
  
  The tool
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;cc-ghost-log&lt;/code&gt; tracks Ghost Days from your &lt;code&gt;~/.claude&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx cc-ghost-log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or browser version (no install): &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;npmjs.com/package/cc-safe-setup&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total Ghost Days and Ghost Day rate&lt;/li&gt;
&lt;li&gt;Ghost Days by day of week (so you can see your patterns)&lt;/li&gt;
&lt;li&gt;Which specific days were ghost days&lt;/li&gt;
&lt;li&gt;Session activity on ghost days (to show &lt;em&gt;why&lt;/em&gt; they were ghost)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data has been uncomfortable. But uncomfortable data is more useful than no data.&lt;/p&gt;




&lt;p&gt;More on Claude Code safety: &lt;a href="https://www.npmjs.com/package/cc-safe-setup" rel="noopener noreferrer"&gt;cc-safe-setup on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>productivity</category>
      <category>data</category>
    </item>
  </channel>
</rss>
