<?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>Forem: dotori</title>
    <description>The latest articles on Forem by dotori (@dotoricode).</description>
    <link>https://forem.com/dotoricode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3849970%2F687252a8-d14d-4dbc-91b5-d02f8c45115c.jpeg</url>
      <title>Forem: dotori</title>
      <link>https://forem.com/dotoricode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dotoricode"/>
    <language>en</language>
    <item>
      <title>The file was still there. That was the problem.</title>
      <dc:creator>dotori</dc:creator>
      <pubDate>Tue, 31 Mar 2026 08:34:32 +0000</pubDate>
      <link>https://forem.com/dotoricode/the-file-was-still-there-that-was-the-problem-3ogn</link>
      <guid>https://forem.com/dotoricode/the-file-was-still-there-that-was-the-problem-3ogn</guid>
      <description>&lt;h2&gt;
  
  
  The failure mode nobody warns you about
&lt;/h2&gt;

&lt;p&gt;When Claude Code deletes a file, you notice immediately. &lt;code&gt;git restore&lt;/code&gt;, back in business.&lt;/p&gt;

&lt;p&gt;The dangerous case is when it &lt;em&gt;doesn't&lt;/em&gt; delete the file.&lt;/p&gt;

&lt;p&gt;A config overwritten with empty values. A &lt;code&gt;hooks.json&lt;/code&gt; that exists but is blank. A &lt;code&gt;settings.local.json&lt;/code&gt; silently reset after an update. The file is present. The watcher sees nothing wrong. But your AI agent is now operating on broken context — and you won't know until the session goes sideways.&lt;/p&gt;

&lt;p&gt;As one developer documented: Claude overwrote an existing config file with blank values — no backup, no warning. The file was still there. That's exactly what makes this kind of corruption harder to notice and harder to recover from than outright deletion.&lt;/p&gt;

&lt;p&gt;This is the problem I built &lt;code&gt;afd&lt;/code&gt; to solve.&lt;/p&gt;




&lt;h2&gt;
  
  
  See it in action
&lt;/h2&gt;

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

&lt;p&gt;Three things happening in that GIF:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;afd start&lt;/code&gt; — zero config, auto-detects your AI tool setup&lt;/li&gt;
&lt;li&gt;A critical config gets deleted mid-session&lt;/li&gt;
&lt;li&gt;Restored in 184ms — before the agent's next command runs&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;&lt;code&gt;afd&lt;/code&gt; (Autonomous Flow Daemon) is a background daemon that acts as an Immune System for your repo. It doesn't just watch for deletion — it validates file content on every change, and restores from a known-good snapshot in &lt;strong&gt;&amp;lt; 270ms&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[afd] 🛡️ hooks.json overwritten with empty values | 🩹 Self-healed in 184ms | Context preserved.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the agent's perspective, nothing happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  The S.E.A.M Cycle
&lt;/h2&gt;

&lt;p&gt;Every file event flows through four stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sense&lt;/strong&gt; — Chokidar detects any &lt;code&gt;unlink&lt;/code&gt; or &lt;code&gt;change&lt;/code&gt; event (&amp;lt; 10ms)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract&lt;/strong&gt; — Health checks validate &lt;em&gt;content&lt;/em&gt;, not just existence (&amp;lt; 5ms)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adapt&lt;/strong&gt; — Matches symptom to stored antibody in SQLite WAL (&amp;lt; 1ms)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutate&lt;/strong&gt; — RFC 6902 JSON-Patch restores to last known-good state (&amp;lt; 25ms)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total: &lt;strong&gt;&amp;lt; 270ms.&lt;/strong&gt; The design constraint was simple — finish before Claude Code's next tool call registers the damage.&lt;/p&gt;




&lt;h2&gt;
  
  
  The non-obvious problems it solves
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Silent corruption is harder than deletion
&lt;/h3&gt;

&lt;p&gt;Deletion is loud. Corruption is quiet. &lt;code&gt;afd&lt;/code&gt; validates file &lt;em&gt;content&lt;/em&gt; on every write — empty values, malformed JSON, blank hooks — not just file presence. The file being there isn't enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Double-Tap Heuristic
&lt;/h3&gt;

&lt;p&gt;How does &lt;code&gt;afd&lt;/code&gt; know if a deletion was intentional?&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; .claudeignore        &lt;span class="c"&gt;# First tap → healed silently&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; .claudeignore        &lt;span class="c"&gt;# Second tap within 30s → afd stands down&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;afd] 🫡 Antibody IMM-001 retired. Double-tap detected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three or more deletes in one second = &lt;code&gt;git checkout&lt;/code&gt; burst, suppression paused entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Antibodies stay current
&lt;/h3&gt;

&lt;p&gt;Snapshots refresh on every valid change. Restores always reflect the latest healthy state — not a stale backup from session start.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;afd score&lt;/code&gt; — value dashboard
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;│  Auto-healed  : 3 background events          │
│  Tokens saved : ~2.9K                        │
│  Time saved   : ~40 min                      │
│  Cost saved   : ~$0.01                       │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Localized in Korean and English. Run &lt;code&gt;afd lang ko&lt;/code&gt; to switch.&lt;/p&gt;




&lt;h2&gt;
  
  
  One command
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# No install needed&lt;/span&gt;
npx @dotoricode/afd start

&lt;span class="c"&gt;# Or install globally&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @dotoricode/afd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero config. Auto-detects Claude Code, Cursor, Windsurf. Injects &lt;code&gt;PreToolUse&lt;/code&gt; hooks silently. Published on npm as &lt;code&gt;@dotoricode/afd&lt;/code&gt; v1.1.0.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The current model is reactive — detect damage, restore. I'm working on a &lt;strong&gt;Workflow Genome&lt;/strong&gt; layer that fingerprints healthy config states proactively, so &lt;code&gt;afd&lt;/code&gt; flags drift &lt;em&gt;before&lt;/em&gt; it becomes corruption.&lt;/p&gt;

&lt;p&gt;Less "immune response." More "immune memory."&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/dotoricode/autonomous-flow-daemon" rel="noopener noreferrer"&gt;https://github.com/dotoricode/autonomous-flow-daemon&lt;/a&gt; | &lt;code&gt;npx @dotoricode/afd start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you've been hit by silent config corruption — not deletion, but quiet overwrites — I'd genuinely like to hear how it manifested.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>devtools</category>
      <category>opensource</category>
      <category>bunjs</category>
    </item>
    <item>
      <title>I built a linter for AI project structure — because every project looked different</title>
      <dc:creator>dotori</dc:creator>
      <pubDate>Sun, 29 Mar 2026 19:38:11 +0000</pubDate>
      <link>https://forem.com/dotoricode/i-built-a-linter-for-ai-project-structure-because-every-project-looked-different-30jf</link>
      <guid>https://forem.com/dotoricode/i-built-a-linter-for-ai-project-structure-because-every-project-looked-different-30jf</guid>
      <description>&lt;h2&gt;
  
  
  The problem nobody talks about
&lt;/h2&gt;

&lt;p&gt;Here's a pattern I kept running into:&lt;/p&gt;

&lt;p&gt;I'd start a new project with Claude Code, get into a flow, build something real — and then look at the folder structure a week later and wonder who made these decisions.&lt;/p&gt;

&lt;p&gt;Start 10 projects with AI coding tools, and you'll get 10 different structures. One has &lt;code&gt;CLAUDE.md&lt;/code&gt;, another doesn't. One has &lt;code&gt;.claude/hooks.json&lt;/code&gt;, three others don't even have a &lt;code&gt;.claude/&lt;/code&gt; directory. Documentation lives in &lt;code&gt;docs/&lt;/code&gt; in one project and nowhere in the next.&lt;/p&gt;

&lt;p&gt;Then a teammate joins and the first message is always: &lt;em&gt;"Where's the config? Do we have hooks set up? Is there a plan document somewhere?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The AI tools themselves suffer from this too. Claude Code works better when it has structured context — agent definitions, skill files, templates, policies. But there's no built-in way to check whether your project actually has all of that in place.&lt;/p&gt;

&lt;p&gt;I wanted something like ESLint, but for project layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  So I built bkit-doctor
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;bkit-doctor&lt;/strong&gt; is a CLI that diagnoses your AI-assisted project structure and fixes what's missing — in one command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx bkit-doctor check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bkit-doctor v1.0.0

  Project Structure Check
  ────────────────────────────────────
  [PASS]  .claude/ directory
  [PASS]  CLAUDE.md
  [FAIL]  .claude/hooks.json
  [FAIL]  .claude/settings.local.json
  [WARN]  docs/01-plan/
  [WARN]  docs/02-design/
  [PASS]  docs/03-task/
  [PASS]  docs/04-report/
  [FAIL]  Agent definitions (4 files)
  [FAIL]  Skill files (7 files)
  ...

  Result: 6 PASS · 2 WARN · 6 FAIL
  Recommendation snapshot saved.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then fix everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx bkit-doctor fix &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Missing directories created, config files scaffolded, agent definitions generated — all without touching anything that already exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things that matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Diagnose: 14 checks, one command
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;bkit-doctor check&lt;/code&gt; inspects your project for 14 items across 6 categories: directory structure, config files, documentation scaffolds, agent definitions, skill files, templates, and policies.&lt;/p&gt;

&lt;p&gt;Hard failures (missing &lt;code&gt;.claude/&lt;/code&gt; or &lt;code&gt;CLAUDE.md&lt;/code&gt;) return exit code 1. Everything else is a warning. Simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fix: scaffold what's missing
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;bkit-doctor fix --yes&lt;/code&gt; runs diagnosis, figures out what's missing, and creates it. One command, no prompts.&lt;/p&gt;

&lt;p&gt;Want to see what it would do first?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bkit-doctor fix &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also pick specific targets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bkit-doctor init &lt;span class="nt"&gt;--target&lt;/span&gt; hooks-json
bkit-doctor init &lt;span class="nt"&gt;--targets&lt;/span&gt; agents-core,docs-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use presets for different project sizes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bkit-doctor preset list
&lt;span class="c"&gt;# default  — full structure (8 targets)&lt;/span&gt;
&lt;span class="c"&gt;# lean     — minimal (config + agents only)&lt;/span&gt;
&lt;span class="c"&gt;# workflow-core — agents + skills + templates + policies&lt;/span&gt;
&lt;span class="c"&gt;# docs     — documentation scaffold only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Safe by design
&lt;/h3&gt;

&lt;p&gt;This was non-negotiable: &lt;strong&gt;existing files are never overwritten&lt;/strong&gt; unless you explicitly pass &lt;code&gt;--overwrite&lt;/code&gt;. Even then, &lt;code&gt;--backup&lt;/code&gt; creates copies before touching anything.&lt;/p&gt;

&lt;p&gt;No surprises. No lost work. Preview everything with &lt;code&gt;--dry-run&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you'd actually use this
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Starting a new project:&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="nb"&gt;mkdir &lt;/span&gt;my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-app
git init
npx bkit-doctor fix &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;span class="c"&gt;# Full AI-friendly project structure in seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adding structure to an existing project:&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="nb"&gt;cd &lt;/span&gt;existing-project
npx bkit-doctor check          &lt;span class="c"&gt;# see what's missing&lt;/span&gt;
npx bkit-doctor fix &lt;span class="nt"&gt;--dry-run&lt;/span&gt;  &lt;span class="c"&gt;# preview the fix&lt;/span&gt;
npx bkit-doctor fix &lt;span class="nt"&gt;--yes&lt;/span&gt;      &lt;span class="c"&gt;# apply it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CI gate for project health:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/check.yml&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Verify project structure&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx bkit-doctor check&lt;/span&gt;
  &lt;span class="c1"&gt;# exits 1 if .claude/ or CLAUDE.md is missing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  About bkit
&lt;/h2&gt;

&lt;p&gt;bkit-doctor was inspired by &lt;a href="https://github.com/popup-studio-ai/bkit-claude-code" rel="noopener noreferrer"&gt;bkit&lt;/a&gt;, a PDCA-based development workflow framework for Claude Code. I learned a lot about structured AI collaboration from bkit's methodology, and that shaped how this tool thinks about project structure.&lt;/p&gt;

&lt;p&gt;That said — &lt;strong&gt;bkit-doctor is fully independent&lt;/strong&gt;. It doesn't require bkit, doesn't include bkit code, and works with any AI coding tool. If you do use bkit, the scaffolding is optimized for its workflow. If you don't, you still get a clean, well-organized project structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx bkit-doctor check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/dotoricode/bkit-doctor" rel="noopener noreferrer"&gt;github.com/dotoricode/bkit-doctor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;a href="https://www.npmjs.com/package/bkit-doctor" rel="noopener noreferrer"&gt;npmjs.com/package/bkit-doctor&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this solves a problem you've had, a star on the repo would be appreciated. And if you have ideas for additional checks or presets, issues and PRs are welcome.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;bkit-doctor is an independent open-source project (Apache 2.0). It is not affiliated with the bkit team.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>vibecoding</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
