<?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: HARSHAD BIRADAR</title>
    <description>The latest articles on DEV Community by HARSHAD BIRADAR (@harshad_ee_a376088a466eef).</description>
    <link>https://dev.to/harshad_ee_a376088a466eef</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%2F3822016%2Ff206c0eb-c7e6-4737-ac62-33a82342e0ff.png</url>
      <title>DEV Community: HARSHAD BIRADAR</title>
      <link>https://dev.to/harshad_ee_a376088a466eef</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshad_ee_a376088a466eef"/>
    <language>en</language>
    <item>
      <title>What If LLM Agents Coordinated Through the Filesystem Instead of HTTP?</title>
      <dc:creator>HARSHAD BIRADAR</dc:creator>
      <pubDate>Fri, 13 Mar 2026 10:04:27 +0000</pubDate>
      <link>https://dev.to/harshad_ee_a376088a466eef/what-if-llm-agents-coordinated-through-the-filesystem-instead-of-http-jkp</link>
      <guid>https://dev.to/harshad_ee_a376088a466eef/what-if-llm-agents-coordinated-through-the-filesystem-instead-of-http-jkp</guid>
      <description>&lt;h1&gt;
  
  
  What If LLM Agents Coordinated Through the Filesystem Instead of HTTP?
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;An architecture I've been thinking through — and why I think it might actually work.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Frustration That Started This
&lt;/h2&gt;

&lt;p&gt;Every time I look at multi-agent AI frameworks, I see the same pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install LangChain / CrewAI / AutoGen&lt;/li&gt;
&lt;li&gt;Set up 4 different API keys&lt;/li&gt;
&lt;li&gt;Configure a message broker or HTTP server for agent communication&lt;/li&gt;
&lt;li&gt;Handle serialization, retries, timeouts, and routing&lt;/li&gt;
&lt;li&gt;Debug a system where the state lives... somewhere inside a Python object in memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For what? To have two LLM processes pass text to each other.&lt;/p&gt;

&lt;p&gt;I'm a systems programmer. My instinct when I see this is: &lt;strong&gt;this is too much infrastructure for the actual problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I started asking a simpler question: &lt;em&gt;What's the minimum coordination layer two agents actually need?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The answer I keep coming back to has been sitting in Unix since the 1970s.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Insight I Can't Stop Thinking About
&lt;/h2&gt;

&lt;p&gt;LLM agents have a property that's easy to overlook: &lt;strong&gt;they are extraordinarily slow workers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A single inference call takes 2–10 seconds. Your agents are not going to saturate a network pipe. They're not going to race condition your shared memory. The bottleneck is never the IPC layer — it's always the model.&lt;/p&gt;

&lt;p&gt;This changes the calculus completely. Every classical argument against filesystem-based IPC — performance, latency, throughput — evaporates when your workers operate in seconds, not microseconds.&lt;/p&gt;

&lt;p&gt;What's left are the advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;State is just files.&lt;/strong&gt; Human-readable, inspectable, grep-able.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crash recovery is free.&lt;/strong&gt; If an agent dies mid-task, the file is still there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No serialization protocol.&lt;/strong&gt; Agents write markdown. Other agents read markdown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debuggability is trivial.&lt;/strong&gt; Your logs ARE your state. &lt;code&gt;ls tasks/&lt;/code&gt; is your dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero dependencies.&lt;/strong&gt; No broker. No database. No framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the Unix philosophy applied to LLM agents: &lt;em&gt;write programs that communicate through text streams, because that is a universal interface.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture I'm Designing
&lt;/h2&gt;

&lt;p&gt;Here's the directory structure I'm thinking through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workspace/
├── manifest.json              ← coordinator's index, tracks all tasks
├── tasks/
│   ├── task_001_pending.md
│   ├── task_002_inprogress_agent_a.md
│   └── task_003_done.md
├── agents/
│   ├── orchestrator.md        ← system prompt / role definition
│   ├── agent_a.md
│   └── agent_b.md
└── outputs/
    └── task_003_result.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things coordinate everything:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Filename encodes state.&lt;/strong&gt; &lt;code&gt;task_001_pending.md&lt;/code&gt; → &lt;code&gt;task_001_inprogress_agent_a.md&lt;/code&gt; → &lt;code&gt;task_001_done.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;manifest.json&lt;/code&gt; is the coordinator's index.&lt;/strong&gt; Tracks all tasks, ownership, timestamps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No agent talks directly to another agent. They communicate by mutating the filesystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Approach 1: Versioned File Naming
&lt;/h2&gt;

&lt;p&gt;The simpler, more crash-safe approach I want to explore first.&lt;/p&gt;

&lt;h3&gt;
  
  
  The state machine lives in the filename
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;task_001_pending.md              → available for any agent to pick up
task_001_inprogress_agent_a.md   → agent renames it (atomic claim)
task_001_done.md                 → agent renames on completion
task_001_failed.md               → unrecoverable error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Renaming a file is atomic on POSIX filesystems. That's your concurrency primitive — no explicit locks needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the manifest.json would look like
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tasks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"task_001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"done"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agent_a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-03-13T10:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"completed_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-03-13T10:00:42Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"output"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"outputs/task_001_result.md"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conceptual agent loop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;pending&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tasks/*_pending.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;

    &lt;span class="n"&gt;task_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;claimed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;claim_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# atomic rename
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;claimed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;  &lt;span class="c1"&gt;# another agent got it first
&lt;/span&gt;
    &lt;span class="n"&gt;task_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claimed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;write&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;outputs/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;_result.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claimed&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;tasks/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;_done.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;update_manifest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;done&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;h3&gt;
  
  
  Crash recovery — the part I find most compelling
&lt;/h3&gt;

&lt;p&gt;If an agent dies mid-task, the file sits at &lt;code&gt;task_001_inprogress_agent_a.md&lt;/code&gt;. The orchestrator can detect stale &lt;code&gt;inprogress&lt;/code&gt; files older than a threshold and reset them to &lt;code&gt;pending&lt;/code&gt;. No data lost. No complex recovery logic. The filesystem is your persistent state.&lt;/p&gt;




&lt;h2&gt;
  
  
  Approach 2: Named Pipes (FIFOs)
&lt;/h2&gt;

&lt;p&gt;For use cases where you want real-time streaming handoff between two agents rather than polling.&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;mkfifo &lt;/span&gt;workspace/pipes/orchestrator_to_agent_a
&lt;span class="nb"&gt;mkfifo &lt;/span&gt;workspace/pipes/agent_a_to_orchestrator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Orchestrator sends task downstream
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pipes/orchestrator_to_agent_a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Agent reads, processes, responds back
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pipes/orchestrator_to_agent_a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pipes/agent_a_to_orchestrator&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When I'd reach for pipes vs versioned files
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tasks are independent, parallel&lt;/td&gt;
&lt;td&gt;Versioned files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sequential pipeline, output feeds next agent&lt;/td&gt;
&lt;td&gt;Named pipes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Crash recovery is critical&lt;/td&gt;
&lt;td&gt;Versioned files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time streaming between two agents&lt;/td&gt;
&lt;td&gt;Named pipes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;More than 2 agents coordinating&lt;/td&gt;
&lt;td&gt;Versioned files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;My current thinking: &lt;strong&gt;start with versioned files.&lt;/strong&gt; Pipes are compelling for strict sequential pipelines but add blocking complexity that's hard to debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  State Management: Two-Layer Design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Layer 1 — Filename (per-task state)
&lt;/h3&gt;

&lt;p&gt;Atomic, visible at a glance, no extra tooling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2 — manifest.json (system state)
&lt;/h3&gt;

&lt;p&gt;Single source of truth. Write atomically: write to &lt;code&gt;manifest.tmp.json&lt;/code&gt;, rename to &lt;code&gt;manifest.json&lt;/code&gt;. POSIX rename is atomic — safe for concurrent readers.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Would and Wouldn't Solve
&lt;/h2&gt;

&lt;h3&gt;
  
  
  It would solve:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Framework fatigue — zero dependencies&lt;/li&gt;
&lt;li&gt;Debuggability — state is always inspectable on disk&lt;/li&gt;
&lt;li&gt;Crash recovery — filesystem is persistent by default&lt;/li&gt;
&lt;li&gt;Context isolation — each agent is an independent CLI process&lt;/li&gt;
&lt;li&gt;Observability — &lt;code&gt;watch -n1 ls tasks/&lt;/code&gt; is literally your dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  It wouldn't solve:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Distributed systems — agents must share a filesystem (same machine or NFS)&lt;/li&gt;
&lt;li&gt;High throughput — if you need 1000 tasks/sec, use a proper queue&lt;/li&gt;
&lt;li&gt;Real-time streaming — versioned files add ~2s polling latency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is deliberately a &lt;strong&gt;single-machine, low-throughput, high-debuggability architecture.&lt;/strong&gt; I think that matches the actual deployment reality of most local LLM agent use cases — which are rarely distributed, rarely high-throughput, but almost always painful to debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Think This Direction Is Worth Exploring
&lt;/h2&gt;

&lt;p&gt;Current agent frameworks are built assuming agents are fast, distributed, and network-native. They inherit the full complexity of distributed systems design.&lt;/p&gt;

&lt;p&gt;LLM agents are none of those things. They're slow, usually running locally or single-tenant, and their output is human-readable text.&lt;/p&gt;

&lt;p&gt;The filesystem is a better fit for these actual properties. The 1970s Unix designers had this right for a different reason — and it might be accidentally correct again for a new one.&lt;/p&gt;

&lt;p&gt;I'm working on a reference implementation and plan to share it once it's solid enough to be useful. Would be genuinely interested in whether others have tried this approach or hit the walls I'm anticipating — especially around the atomic rename behavior on non-POSIX filesystems (Windows, NFS edge cases).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Harshad Biradar — Systems programmer, building things from first principles.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>a2a</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
