← Back to writing

How I Work With Coding Agents Today

Living doc This article evolves over time as my workflow changes

My current workflow with Linear, Cursor CLI, and Obsidian. A live article, updated as the flow changes.

Updated aiagentsworkflowengineeringproductivity

A few months ago I started using agents for coding work. Not as a copilot suggesting lines, but as a team that works while I’m not around. I learned something quickly though: agents don’t replace the driver. They free you to be a better one.

Here’s the split. For grind work, well-defined tasks, repeatable changes, automated reviews, agents run on their own. For critical paths, architectural decisions, the things that actually matter, I’m still the one driving. I use Cursor, Codex, or Claude Code, but I’m at the wheel. What changed isn’t who does the work. It’s how much heavy lifting I can delegate without losing control of what ships.

The flow

Tasks live in Linear. When an issue is ready for an agent to pick up, I label it “Ready For Claw”. That’s the starting signal.

The orchestrator is OpenClaw, running a periodic heartbeat. Each tick checks Linear. If there are “Ready For Claw” tasks, it kicks off the coder. If there are PRs in “In Review”, it kicks off the reviewer. Without the heartbeat, nothing happens. It’s the actual scheduler that wires the pieces together.

OpenClaw heartbeat
Linear Issue labeled Ready For Claw.
Coder agent Cursor CLI loads context and opens the change.
External verification Lint, typecheck, and tests decide if it advances.
PR in review The issue moves to In Review when everything is green.
Kickback The reviewer sends findings back to the coder.
Human approval I review, decide, and merge.
Obsidian Detailed context for the next agent.
Linear Human-readable summary for me.
The agent handles grind inside clear rails: scheduler, verification, review, and persistent memory.

The coder is Cursor CLI running headless in the repo. It picks up the task, reads the context, and gets to work. When it’s done, it runs lint, typecheck, and tests. If they pass, it opens a PR and moves the issue to “In Review”. If they fail, it logs what broke and leaves the issue in “In Progress” for the next attempt. The agent doesn’t decide it’s done. The test suite does.

The reviewer is the same tool with a different model and a different prompt. It reads the diff, reads the task notes, and looks for bugs, architectural issues, broken logic. No style nits. If it finds something, it kicks the task back to the coder with the findings. If not, it leaves it ready for my approval. Two safety rules. After three kickbacks without resolution, it notifies me and stops. And on any doubt, not just the kickback limit, it also notifies me. The agent doesn’t guess when uncertain.

All persistent state lives in my personal Obsidian vault, in an Agent Notes/ folder next to the project, not inside the code repo. That matters to me. Context lives beside the project, not embedded, and I navigate it with graph view, backlinks, and search like anything else in my vault. The structure:

Agent Notes/
  tasks/LINEAR-ID.md    ← per-task history
  runs/YYYY-MM-DD.md    ← daily log of what ran
  decisions/adr-NNN.md  ← architectural decisions

Each task has its own note with attempt history and findings. Each day has its run log with what executed, what happened, how long it took. Big decisions get logged as ADRs. Agents are amnesiac by nature. The filesystem isn’t.

And there are two output channels not to confuse. Obsidian notes are detailed context for the next agent, machine-readable. Linear comments are summaries for me, human-readable. Every agent action writes to both.

My part is the same as always. I review the PRs the reviewer approved, merge what looks good, handle the ambiguous cases. And for anything on the critical path I sit down and drive directly with Claude Code, Cursor, or Codex. The agent handles the grind. I handle the judgment.

Why it works

Three things hold it together.

Persistence. Agents forget everything when a session ends. The system doesn’t. Every attempt is written down: what was done, what failed, what the reviewer found. The next agent starts with real context, not from zero.

External verification. The agent doesn’t self-assign “done”. Tests, lint, and typecheck are what decide if the work is correct. Without that external signal, agents ship with full confidence even when the code is broken.

Separation of concerns. The coder codes, the reviewer reviews, I approve. Each has a clear role and they don’t overlap. The reviewer never rewrites, it only reports. I never merge without going through the flow, even when I could.