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
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
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
task_001_pending.md
task_001_inprogress_agent_a.md
task_001_done.md
manifest.json
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
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
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
{ "tasks": [ { "id": "task_001", "status": "done", "owner": "agent_a", "created_at": "2025-03-13T10:00:00Z", "completed_at": "2025-03-13T10:00:42Z", "output": "outputs/task_001_result.md" } ]
}
{ "tasks": [ { "id": "task_001", "status": "done", "owner": "agent_a", "created_at": "2025-03-13T10:00:00Z", "completed_at": "2025-03-13T10:00:42Z", "output": "outputs/task_001_result.md" } ]
}
{ "tasks": [ { "id": "task_001", "status": "done", "owner": "agent_a", "created_at": "2025-03-13T10:00:00Z", "completed_at": "2025-03-13T10:00:42Z", "output": "outputs/task_001_result.md" } ]
}
while True: pending = glob("tasks/*_pending.md") if not pending: sleep(2) continue task_file = pending[0] claimed = claim_task(task_file) # atomic rename if not claimed: continue # another agent got it first task_content = read(claimed) result = call_llm(task_content) write(f"outputs/{task_id}_result.md", result) rename(claimed, f"tasks/{task_id}_done.md") update_manifest(task_id, status="done")
while True: pending = glob("tasks/*_pending.md") if not pending: sleep(2) continue task_file = pending[0] claimed = claim_task(task_file) # atomic rename if not claimed: continue # another agent got it first task_content = read(claimed) result = call_llm(task_content) write(f"outputs/{task_id}_result.md", result) rename(claimed, f"tasks/{task_id}_done.md") update_manifest(task_id, status="done")
while True: pending = glob("tasks/*_pending.md") if not pending: sleep(2) continue task_file = pending[0] claimed = claim_task(task_file) # atomic rename if not claimed: continue # another agent got it first task_content = read(claimed) result = call_llm(task_content) write(f"outputs/{task_id}_result.md", result) rename(claimed, f"tasks/{task_id}_done.md") update_manifest(task_id, status="done")
task_001_inprogress_agent_a.md
mkfifo workspace/pipes/orchestrator_to_agent_a
mkfifo workspace/pipes/agent_a_to_orchestrator
mkfifo workspace/pipes/orchestrator_to_agent_a
mkfifo workspace/pipes/agent_a_to_orchestrator
mkfifo workspace/pipes/orchestrator_to_agent_a
mkfifo workspace/pipes/agent_a_to_orchestrator
# Orchestrator sends task downstream
with open("pipes/orchestrator_to_agent_a", "w") as pipe: pipe.write(task_content) # Agent reads, processes, responds back
with open("pipes/orchestrator_to_agent_a", "r") as pipe: task = pipe.read() result = call_llm(task) with open("pipes/agent_a_to_orchestrator", "w") as pipe: pipe.write(result)
# Orchestrator sends task downstream
with open("pipes/orchestrator_to_agent_a", "w") as pipe: pipe.write(task_content) # Agent reads, processes, responds back
with open("pipes/orchestrator_to_agent_a", "r") as pipe: task = pipe.read() result = call_llm(task) with open("pipes/agent_a_to_orchestrator", "w") as pipe: pipe.write(result)
# Orchestrator sends task downstream
with open("pipes/orchestrator_to_agent_a", "w") as pipe: pipe.write(task_content) # Agent reads, processes, responds back
with open("pipes/orchestrator_to_agent_a", "r") as pipe: task = pipe.read() result = call_llm(task) with open("pipes/agent_a_to_orchestrator", "w") as pipe: pipe.write(result)
manifest.tmp.json
manifest.json
watch -n1 ls tasks/ - Install LangChain / CrewAI / AutoGen
- Set up 4 different API keys
- Configure a message broker or HTTP server for agent communication
- Handle serialization, retries, timeouts, and routing
- Debug a system where the state lives... somewhere inside a Python object in memory - State is just files. Human-readable, inspectable, grep-able.
- Crash recovery is free. If an agent dies mid-task, the file is still there.
- No serialization protocol. Agents write markdown. Other agents read markdown.
- Debuggability is trivial. Your logs ARE your state. ls tasks/ is your dashboard.
- Zero dependencies. No broker. No database. No framework. - Filename encodes state. task_001_pending.md → task_001_inprogress_agent_a.md → task_001_done.md
- manifest.json is the coordinator's index. Tracks all tasks, ownership, timestamps. - Framework fatigue — zero dependencies
- Debuggability — state is always inspectable on disk
- Crash recovery — filesystem is persistent by default
- Context isolation — each agent is an independent CLI process
- Observability — watch -n1 ls tasks/ is literally your dashboard - Distributed systems — agents must share a filesystem (same machine or NFS)
- High throughput — if you need 1000 tasks/sec, use a proper queue
- Real-time streaming — versioned files add ~2s polling latency