Varunkumar Nagarajan
How many sessions do you run in parallel, right now?
One tab? Three? A window for every ticket?
A ticket lands. You open Claude Code and start a conversation:
You steer it step by step: pointing it at the right repo, course-correcting when it drifts, approving tool calls, testing changes, reviewing the MR.
Four jobs, one you. That's why it's one session at a time.
For a second session to run without stepping on the first, each one needs its own workspace, its own process, its own budget:
One OS process per claimed item. Its own git worktree, its own budget cap, zero inherited MCP servers. Now you can run more than one — if something starts them.
So — who starts the next one?
You do. Every time.
Something has to notice work exists and decide to start it, deterministically, on a schedule:
The model is never invoked during the heartbeat.
The claiming, budget math, and safety self-test are all plain Python. No LLM interaction anywhere in this file.
Both Codex and Claude Code now ship their own scheduling. I keep the trigger outside the agent on purpose:
| Codex | Claude Code (cron / routines) | This approach | |
|---|---|---|---|
| Where the trigger lives | ChatGPT web/desktop — not the CLI | Inside the agent runtime itself | A plain Python heartbeat, no agent involved |
| Who decides "is there work?" | Hosted Codex Cloud, opaque | The model, via a tool call, every tick | A deterministic script — zero model calls |
| Token spend per idle tick | Unknown, hosted | > 0 — the model reasons every wakeup | $0 — nothing to spend on |
| Safety rules | Server-side, undocumented | Per-session hooks | One fail-closed guardrail, shipped in the plugin |
The scheduler doesn't need to be smart. It needs to be free.
Now a few of these are running unattended. What if one
tries git push --force on main? Reads your SSH
key?
Would you even know before it happened?
A permission boundary that doesn't depend on the model behaving — fail closed, not fail open:
What if one just… keeps going? Burning tokens all night?
Who's watching the meter?
Warn at 70% and 80%. Halt at 100%, blocking every tool except the Slack notification. You decide whether to extend it.
You're not staring at any of these terminals anymore. So how do you know what happened?
Do you remember to check back?
Something durable that survives you not watching, and a place status actually shows up:
You stop watching terminals and start reading a thread.
This works for one kind of ticket. What about something completely different — a dependency upgrade?
Do you rebuild the whole thing?
Nothing in the scheduler, isolation, guardrail, budget, or shared-state layer changes when you add one of these.
Six questions. Six pieces. All of it running right now.
It usually doesn't merge or ship. It produces a result for an engineer to judge.
This follows the "Loop Engineering" approach described by Addy Osmani. The central discipline: automate the toil, not the judgment.
A loop is a YAML config and an entry skill. Nothing else changes.
Nine phases: scenario, repro, RCA, fix, 20x validation, review, MR. Hard gate: must reproduce before it can fix.
Investigates the underlying cause and surfaces a triage summary. Touches no code. Three phases.
Scans manifests for outdated/vulnerable deps, creates upgrade branches, runs tests, raises MRs.
Triages severity, identifies affected code paths, drafts remediation patches for review.
If another machine claims it first, the loser yields. No coordination overhead.
last_sync_timestamp, mismatched
values between two replicas, dataset shard 4567.
Automate the toil.
Not the judgment.
"Verification is still on you. A loop running unattended is
also a loop making mistakes unattended."
— Addy
Osmani
Currently: proof of concept, unit-tested.
One loop drifts eventually — metrics get gamed, targets go stale, nobody watches the watcher. The fix isn't a smarter loop, it's topology:
None of it works without anchors — immovable ground truth (real revenue, a real reproduction, a real diff) that resists getting gamed. Today we have one loop. The graph is what comes after the second and third.
Build the loop. Automate the toil.
Stay the engineer
who decides what ships.
Varunkumar Nagarajan
Let's talk — your use cases, your loops.