Sitemap
Towards AI

We train AI Engineers. We deploy Enterprise AI. Join 100K+ AI practitioners at Towards AI Academy or reach out for help making your company AI native. towardsai.com

Harnesses: Eager vs. Just-in-Time

The bet every coding agent makes before it writes a line of code.

10 min readJul 19, 2026

--

Read the article for free here.

Press enter or click to view image in full size
Created using matplotlib, more on this later.

I’ve been building my own coding harness, and the thing I kept obsessing over was the first turn, time to first byte, and maximizing cache reads while minimizing everything else (input, output, cache creation tokens, server latency, etc.). Those numbers sent me down a rabbit hole comparing every harness I could get my hands on.

Essentially, every coding agent makes a bet before the first tool call fires. How much of your workspace should the model see before it starts reasoning, and how much should it have to go find?

That one decision drives almost everything people argue about with these tools. Token bills. Latency. Whether the agent’s picture of your repo is current or twenty minutes old. Whether it behaves the same on a weekend project and a monorepo.

I’ve boiled this down into two camps.

Eager Hydration: Cline’s Bet

Open a task in Cline and before the model has thought about your request at all, it’s holding a recursive listing of every file path in your working directory. This lives in a block called environment_details. Technically that’s injected context riding alongside the system prompt rather than part of it, though for cost purposes the distinction barely matters. Cline refreshes it as the session goes.

The team is upfront about the philosophy here. The directory structure exists so the model never has to rediscover your project’s shape. They’ve described the system prompt as a constitution, tools, environment, preferences, all bundled into one brief before any work starts. I actually respect how legible the bet is. Pay a tax at the start of every task, sized to your workspace, and in exchange the agent never opens with “so what’s in this repo?”

The catch, of course, is that the map starts rotting the moment someone adds or deletes a file. Hence the refreshing. More on why that matters later, because it’s not the token cost that gets you.

A Second Flavor of Eager: Aider’s Curated Map

Aider is eager too, but it looked at Cline’s phone-book approach and decided to send an org chart instead.

Tree-sitter parses the repo. Aider builds a graph of which files define and reference which symbols, then runs PageRank over it, weighted toward files already in the conversation. Out comes a “repo map”, the most-referenced classes and functions in your codebase, as elided snippets, binary-searched down to fit about 1,024 tokens. Ships with every request. (look up graphiffy in github)

Same philosophy as Cline but the map goes out before the agent asks for anything. Radically different bill. Whether a ranked summary actually beats a complete listing is a genuinely open question, and I suspect the answer depends on how weird your codebase is. PageRank rewards what’s popular. Your bug is usually somewhere unpopular.

Just-In-Time Search: The Claude Code / Codex / Gemini Bet

Claude Code didn’t arrive at just-in-time search by accident. It got there by reversal, which makes it even more interesting. Anthropic built RAG and vector indexing into early versions, ran it head-to-head against live agentic search, and ripped it out. Boris Cherny, Claude Code’s creator, has said agentic search won by a wide margin in their testing. Not “we preferred it.” Just won.

What’s left is almost embarrassingly simple. Glob for path patterns. Grep for content. Read to pull a file in once it’s confirmed relevant. The agent finds structure by looking for it, the way you’d find and grep your way around an unfamiliar repo yourself. When exploration needs to go deep, Claude Code spawns a read-only Explore sub-agent in a separate context window that comes back with just a summary, so the wandering never pollutes the main session.

There’s a small eager component. CLAUDE.md goes in up front, unconditionally. Conventions, build commands, all that curated stuff. Anthropic calls the whole thing a hybrid, which is fair, and multiple users working on the same repo would still prefix match. Codex CLI and Gemini CLI made the same call, with AGENTS.md and GEMINI.md. There's no pre-built tree. All discovery through search, cost spread across turns.

Where the Tokens Actually Land

Do the totals converge? Somewhat, but cost matters more than the sum.

Cline pays once, at the front, proportional to workspace size. Ten files, basically free. Tens of thousands of paths? Real money, every single task, before any reasoning happens.

The search camp pays in installments. A Glob here, a Grep there, a Read when a candidate is confirmed. Total scales with how many wrong turns the search takes. Notice what it doesn’t scale with is repo size. Grep doesn’t care how big the haystack is. It cares how good your pattern is.

So the curves cross. On a small flat project eager wins, and JIT is paying round-trip latency to learn what one listing would’ve handed over instantly. On a big deep repo it flips.

But here’s the cost that raw token counts miss, and honestly the thing that made me want to write this post is cache economics.

Press enter or click to view image in full size
Context loading philosophy (eager left, JIT right). The y-axis is a rough estimate. Cline and Terminus 2 have long lines because their cost scales with repo size. The JIT cluster has short, nearly flat lines because Glob/Grep cost doesn’t scale with repo size, only with search quality. JIT tools have large dots (org-wide cache sharing possible). Eager tools have small dots (session-scoped, volatile content breaks cache sharing). Not mentioned, Roo Code, as it was a Cline fork, the now Zoo Code.

The Cache Problem Nobody Puts in Their README

Go look at what actually rides inside a real environment_details block sometime. The current time, down to the second. The developer’s open editor tabs. Visible vscode files. A running context-window usage counter.

None of that repeats across sessions. It definitely doesn’t repeat across people. Two engineers, same team, same repo, identical git state. Diverging prefixes, every time because the volatile fields have nothing to do with the code. And prompt caches live and die on identical prefixes. Anthropic’s caching docs are explicit that entries are isolated per organization and workspace, not per user. The headroom for team-level cache sharing is sitting right there in the API. Cline’s design can’t touch it, because the stuff that makes each request unique is embedded inside what should have been the reusable part.

Now flip it. Claude Code’s static layer (system prompt, tool definitions, CLAUDE.md) carries no timestamps, no editor state, nothing personal. Two different engineers on the same repo can, in principle, produce byte-identical prefixes and warm the same cache. I haven’t seen anyone benchmark this at team scale, and I’d love to see the numbers. But structurally, one design permits it and the other forecloses it.

The usual framing for eager-vs-JIT is turns versus tokens. Cline resolves requests in fewer turns because the map’s already loaded and the search camp burns round-trips but keeps each one lean. Fine, true, whatever. The framing I haven’t seen yet are the two philosophies are implicitly betting on who the cache is for. Eager optimizes for the session in front of it. JIT, almost by accident, just by keeping its prefix clean, optimizes for the team.

The Real Axis

Where do you place your bet on staleness versus discovery cost?

Eager says a slightly stale map beats no map, and refreshing keeps the staleness tolerable. JIT says a live query beats any cached map, and the overhead of asking is worth never being wrong about what’s on disk. Neither is right in the abstract. Each is right relative to your repo size, your churn rate, and whether your economics punish tokens or turns. Not which harness is smarter. Which bet, and why.

Cursor Doesn’t Fit, Which Is the Point

Everyone files Cursor next to Cline. IDE-native, feels eager. The mechanics disagree. Cursor never loads a tree. It chunks your codebase locally, embeds the chunks, keeps them in a persistent vector database, and runs nearest-neighbor search at query time. What lands in context on any turn is a targeted result, not a map.

Get Jordan Carson’s stories in your inbox

Join Medium for free to get updates from this writer.

Eager about infrastructure, just-in-time about retrieval. The expensive part gets paid once and updated incrementally, not fresh per task. It’s genuinely a third bet, build a retrieval system upfront, then search it like Glob and Grep, just semantically instead of lexically. Also worth noting this is exactly the architecture Anthropic tested and cut. Cursor kept it and built a business on it. Somebody’s wrong here. Or, more likely, they’re optimizing for different users.

Three That Break the Frame

Terminus 2 out-JITs everybody. Raw dogging it like the 1970s. No Glob, no Grep, no Read. No file tools, period. Raw Bash over tmux, and the model decides for itself whether to grep, find, or open vim like an animal. Even context management is reactive. Summarization fires only when the window’s nearly full. If Claude Code is just-in-time search, Terminus 2 is just-in-time everything.

OpenCode is confirmation rather than a new philosophy. AGENTS.md up front (CLAUDE.md fallback included), Glob/Grep/Read for the rest, Explore and Scout subagents for isolated discovery. An independent open-source team looked at the same problem and drew the same architecture.

Hermes Agent isn’t even on this axis. It’s a persistent multi-platform agent (CLI, messaging apps, scheduled jobs) and its defining choice is a three-tier system prompt (stable, context, volatile) with skills loaded as slash commands, all organized around one rule treated as near-sacred. Never invalidate the prompt cache.

Credit Where It’s Due

The context axis isn’t what separates these tools in daily use. So, briefly, my boiled-down version of what each is actually good at.

Cline gives you the deepest VS Code integration of the group, and its plan/act split, where the agent proposes first and executes only after approval, is the right shape for anyone who wants gates on every change. Aider is the one for people who think in diffs. Git-native, every accepted change its own commit, runs against basically any model. Claude Code is built for walking away sub-agents, hooks, background execution, and multi-step refactors with minimal supervision. Codex CLI puts OpenAI’s reasoning models in a cloud sandbox and earns its keep on algorithmically hard problems where reasoning quality beats speed.

Gemini CLI deserves its own sentence because it can hold a 1M-token window, about an hour of video at default resolution, up to three videos at reduced, next to your code and docs in the same request. Wild. Google’s own testing shows it reasoning over 90-minute videos with synchronized audio in one pass. I’ve read that it can read a two-hour video in minutes, which appears to be accurate, but haven’t personally tested this claim.

Cursor owns the flow-state niche, with the tightest autocomplete-to-agent loop of anything here. Terminus 2, with no scaffolding at all, is the closest thing this space has to a control group, which makes it the right benchmark for a model’s raw ability. OpenCode is Claude Code’s ergonomics without the lock-in, model-agnostic, open-sourced. And Kilo Code, post-migration, is effectively OpenCode plus managed billing and a model marketplace for teams that want flexibility without running their own key management.

A Vendor Switched Camps, In Public

Most harnesses pick a philosophy at birth and die with it. Kilo Code didn’t, and that’s what makes that transition useful info.

Original Kilo was a Cline fork, same lineage as Roo Code, same eager environment_details listing. In April 2026 they rewrote the CLI from scratch, and instead of refining their own eager approach they forked OpenCode outright. The new Kilo CLI runs OpenCode’s tool registry verbatim. Glob, Grep, Read, ripgrep underneath, explore subagent and all. The whole just-in-time toolkit, inherited rather than rebuilt.

You almost never get to watch this in the open. Real product, real users, full rewrite on the line, and the team crossed the aisle. By the time Kilo moved, the JIT camp had been settled for over a year. Claude Code in February 2025, Codex CLI in April, Gemini CLI in June. Three labs, no shared code, same tool shape inside four months, and at least one of them got there only after building the alternative and cutting it. If you read my convergent engineering piece, you know the pattern. The alternatives get tried, and they fail or converge in the same way everywhere.

Who Is Your Harness For?

Here’s where I land, and the thought I keep circling back to.

Strip out the token math and the two philosophies stop being about efficiency. They’re answers to a question nobody asked out loud. Who is this agent’s context for?

Eager hydration answers, this developer, this session, this moment, right down to the open tabs and the timestamp. The richest possible picture of one person’s now. The price of that attachment is context nobody else can reuse, aging from the second it’s assembled.

Just-in-time search gives a different answer. By refusing to let anything personal or perishable into the prefix, it produces context that any engineer on the team could share, cache, and trust.

Agents are about to stop being one developer’s sidekick. They’re becoming fleets, parallel, backgrounded, several of them working the same repo for a whole team at once. In that world, context scoped to one person’s editor tabs isn’t inefficient. It’s the wrong abstraction entirely.

The harnesses that win the next phase won’t be the ones that know the most about your session. They’ll be the ones whose knowledge was built to be shared.

The Pattern Scales

Once you step back far enough to see it, the comparison actually surfaces.

The problem these tools are solving isn’t file discovery. It’s context admission control. Aka what gets into the model’s window, when, and why. Cline’s answer is to admit everything upfront and pay the tax. Claude Code’s answer is to admit nothing until something earns its way in through search. The industry spent about a year trying both and converged hard on the latter.

That principle doesn’t stop at files. The same problem exists one layer up with skills. A plugin with 90 doesn’t load all 90 into the system prompt any more than a well-designed harness loads your entire file tree. It exists with MCP servers, where a catalog of tools has the same admission problem as a catalog of skills. It exists with agents themselves in a multi-agent system, where spawning every possible sub-agent upfront is the agentic equivalent of eager hydration.

The fix is the same in every case. You need three things. A catalog with enough semantic definition that retrieval can work, a classifier or similarity search layer that admits only what the current request actually needs, and a clean separation between what’s always loaded and what earns its way in. pgvector for the catalog. Embeddings or a lightweight router for the classifier. A stable, cacheable prefix that never changes between requests is the foundation.

Files, skills, tools, more skills, agents, policies. The admission control problem is the same. The architecture that solves it is the same. The ones that figure out just-in-time capability loading will have the same cost and cache advantage over the ones that don’t.

The List

--

--

Jordan Carson
Jordan Carson

Written by Jordan Carson

Applied AI Engineer @JPMorgan, lives on Earth 🌎. Some of this, most of that. Overlord of the cookie jar

Towards AI
Towards AI

Published in Towards AI

We train AI Engineers. We deploy Enterprise AI. Join 100K+ AI practitioners at Towards AI Academy or reach out for help making your company AI native. towardsai.com