DEV Community

signalscout
signalscout

Posted on

Stop Chatting With Your Agent. Use Files.

OpenClaw Challenge Submission 🦞

This is a submission for the OpenClaw Writing Challenge

I stopped talking to my agents. My throughput went up.

Not a little. A lot. The interface changed and the work got better. That's the whole post, but I'll spend the next 900 words earning it.

Chat is the wrong shape for real work

The terminal pane is seductive. You type, it types back, dopamine, repeat. Feels like progress. It isn't.

Here's what chat-as-interface actually gives you:

  • State lives in the model's head. Scroll up far enough and you're arguing with a ghost. The agent "remembers" until it doesn't.
  • Every turn pays rent. Tool output, file reads, half-finished reasoning — it's all still there, burning tokens, dragging attention.
  • No parallelism. One window, one conversation, one thread of thought. If you want two agents on two tasks, you open two terminals and pray neither one hallucinates the other's context.
  • No audit trail that isn't a transcript. When something went wrong three days ago, you're grepping scrollback.

Chat optimizes for the feeling of collaboration. Files optimize for the fact of it.

The fix: files are the contract

The pattern I've settled on — and the one OpenClaw is quietly built around — is this: the chat window is for routing. Files are the work.

Every agent in my setup reads from and writes to a small set of root-level markdown files. Not a database. Not a vector store. Plain files, in the workspace, one concern per file:

~/.openclaw/workspace/
├── AGENTS.md          # rules of the road
├── SOUL.md            # voice, posture, biases
├── NEXT_TICKET.md     # the one thing to do right now
├── STATUS.md          # current state of the world
├── TASKS.md           # backlog, classified
├── BLOCKER.md         # human gate — exists = I'm stuck
├── MEMORY.md          # index into memory/
└── outputs/           # artifacts go here, not into chat
Enter fullscreen mode Exit fullscreen mode

The agent doesn't remember what it's doing. It reads NEXT_TICKET.md. It doesn't guess at tone. It reads SOUL.md. It doesn't narrate its plan into the chat window and hope you catch it — it updates STATUS.md, writes the artifact to outputs/, and if something's wrong, it drops BLOCKER.md and stops.

The model's context window becomes disposable. The filesystem is the source of truth.

A worked example

Here's what AGENTS.md actually looks like in my workspace. Not a philosophy doc — a routing table:

## Work Categories

### 🔴 CRITICAL (do now, in context)
- Active blocker Ryan is waiting on
- Bug breaking a running system
- Ryan says "now" or "do this"

### 🟡 QUEUED (write ticket, do next)
- Features on active projects
- Non-blocking bugs
→ Write to TASKS.md, acknowledge with one line. Do NOT start.

### 🟢 DEFERRED (log it, do later)
→ Write to TASKS.md with [DEFERRED] tag. Move on.

### ⚪ QUESTION (answer, don't build)
→ Plan on paper. Do NOT start building unless Ryan says "do it."
Enter fullscreen mode Exit fullscreen mode

That's the whole routing logic. No prompt engineering gymnastics. No "You are a helpful assistant who..." The agent reads this file at the start of every turn and classifies before touching anything.

NEXT_TICKET.md is the ticket the coder agent picks up. It looks like this:

# TICKET: Provider circuit breaker for ContextClaw

## Scope
Track consecutive 429/quota errors per provider.
After 3 failures, mark provider "tripped", skip in fallback chain.
Auto-reset at midnight ET or after configurable cooldown.

## Acceptance
- Gemini 429 three times → next call routes to Groq without retry
- TUI footer shows "Gemini: TRIPPED (resets 00:00 ET)"
- State persists across restarts (./state/providers.json)

## Out of scope
- Per-endpoint granularity (provider-level is fine for v1)
- UI for manual reset (kill the file, it's fine)
Enter fullscreen mode Exit fullscreen mode

That's a ticket a coding agent can pick up cold. No "as we discussed." No Slack archaeology. A model I spun up yesterday and a model I spin up next month read the same file and do the same job.

When it's done, the artifact lives in outputs/, not in the chat log. STATUS.md gets one line appended. If the agent hit a wall it can't cross — auth, billing, an irreversible action — it writes BLOCKER.md and stops. The existence of the file is the signal. I don't have to read it in a transcript; I see it in ls.

Why this generalizes

File-as-interface isn't an OpenClaw trick. It's the shape every serious multi-agent setup converges on, because it solves problems chat cannot:

  • Parallelism is free. Three agents can read TASKS.md and claim different tickets. The filesystem is the lock.
  • Handoffs stop costing context. Sub-agent writes to a file. Parent reads the file when it needs to. The parent's context stays clean, and that savings compounds per turn. The rule I enforce in AGENTS.md is blunt: sub-agents write results to files. They do NOT report back into parent context. Completion = file exists at expected path. Not a message.
  • Humans can review without being in the loop. I scroll STATUS.md instead of 40k tokens of scrollback. Approval becomes binary. ✅ or ❌. I am the reviewer, not the driver.
  • State survives the model. When the next frontier model ships — and it's shipping soon — my whole workflow moves over with a config change. The files don't care which model read them.

That last one matters more than it sounds. The models are a commodity that gets better every month. The artifacts are the moat.

The tell

Here's the heuristic I use now: if an agent's answer isn't somewhere I can cat, it didn't happen.

Chat is where you decide what to build. Files are where building happens. The moment you stop treating the terminal as the workspace and start treating it as the router — pointing at files, not producing prose — the whole thing gets faster, cheaper, and more honest about what's actually done.

Open a file. Close the chat. Ship the artifact.

Top comments (0)