At Metaview, we build AI agents for recruiting: Sourcing, Application Review, Screening, Reports and more. They all run on one shared harness.

It didn't start that way. Our earliest agent ran on AWS Step Functions, and after that each one was built differently: one agent on LangGraph, another on the OpenAI Responses API, others on hand-rolled loops. Every new product meant solving the same problems again: sandboxes, sessions, streaming, observability, model access. That was partly deliberate: trying different approaches taught us what worked, what didn't, and what was worth copying.

Today a new agent is a prompt, some skills and a small config. Standing one up takes under two hours, down from several days.

It started with Ramp's background agent

In January 2026, Ramp wrote about Inspect, their internal background coding agent. Each session runs in its own Modal Sandbox, with OpenCode as the agent inside. By February it was starting over half of Ramp's merged PRs.

Where it started: Apurv sharing Ramp’s post, and Keir’s reply the next day

Within days, Keir had built Rook, our own version on the same blueprint. It started as a coding agent. Now it's used across the company: opening and reviewing PRs, triaging alerts, writing presentations, helping with customer requests and answering questions about how the product works. Think Claude Tag, five months before Claude Tag launched.

Rook was also a better agent than the ones we shipped to customers. It had a real filesystem, bash and long-running sessions, and it planned its own work. Our LangGraph agent didn't. LangGraph has you lay out an agent like a flowchart: you decide every step, and the order they run in, before the agent ever sees a request. That breaks down on real hiring briefs. When a search came back thin, the agent couldn't step back and rethink the brief unless we'd drawn that path in advance, and every new behavior meant redrawing the flowchart and redeploying. The flowchart had become the limit on how smart the agent could be.

So we moved our product agents onto Rook's stack.

What the harness is

The harness is a set of shared libraries and one deploy pipeline, running on providers we already trust: Cloudflare, Modal and AWS.

  • Control plane. Each session gets a Cloudflare Durable Object that handles streaming, state, scheduling and messages between agents.
  • Sandbox. The agent runs in a Modal Sandbox. The loop inside is OpenCode today, but it's swappable: change it once and every agent gets the new loop on the next deploy.
  • Broker. The sandbox holds no credentials. To read data or take an action, the agent calls a broker API on AWS Lambda with a short-lived session token, and the broker decides what that session may do. Each agent has its own broker, built from the same shared pieces.
  • Persistence. When a session goes idle, we snapshot its files to storage and shut the sandbox down. When the user returns, weeks or months later, a new sandbox restores it and the agent picks up where it left off.

Only the highlighted boxes change from one agent to the next: the agent itself and its broker. Everything else is shared.

An agent is what's left: a system prompt, a folder of skills, scripts it calls from bash, and a config file. Our agents have very few tools in the usual sense. Most of what other teams would build as tools, we ship as scripts, and they're better in several ways: the agent can chain them together, fix them on the fly when they don't fit, and read a script's docs only when it needs them, instead of holding every tool description in context up front.

That's also why we run the agent loop inside the sandbox, which goes against current advice. The popular approach is to keep the loop outside and give it a remote sandbox to call into, partly so credentials never sit next to code the agent is running. We went the other way because our agents work through their filesystem and scripts natively, and that only works if the loop lives next to them. The broker handles the security concern: the sandbox never holds credentials, so there's nothing in it worth stealing.

Owning the stack means we can add hooks anywhere. Our agents can rewrite their own scripts mid-run, so one hook checks each failure against what we shipped and stops an agent's experiments from paging an engineer. And any fix lands everywhere: when one agent finds a bug, the fix goes in the harness and every agent gets it.

Why we didn't buy one

In May, I argued that we should. Letting a provider run the loop, state and sandboxes seemed like the obvious call, the same way you'd use a managed database. The team pushed back, and they were right.

The biggest reason is models. Hosted agent platforms tie you to one lab's models, and we want the best model for each agent. On our harness, the model is a config value: switching Sourcing between Opus 5.5 and GPT-6.1 Sol is a one-line change, and open-weight models work the same way, so a new model can be running behind a real agent the afternoon it ships. The same flexibility lets us route around rate limits and choose providers for customers with data residency needs.

Hosted platforms also cap how far you can customize the loop, and those details are where our product feels fast or broken. Frameworks still leave you running the infrastructure, inside someone else's abstractions.

And owning it is cheap now. Our fillmore prototype took two days, forked off Rook, and agents write much of the harness code.

Testing on the harness

A shared harness also changed how we test. Our agents can run for an hour, call 1,000 scripts and take a different path every time, so there's no single right path to check. Our evals are entirely output-derived: we judge what the agent produced, not how it got there.

Because every agent runs on the harness, every agent exposes the same session interface. So our evals run on the harness too. An orchestration agent starts real sessions, drives them like a user would, and grades the outputs. One orchestrator can test any agent, and since each session gets its own sandbox, we can run as many in parallel as we like. The harness is built for customer volume, and no eval comes close.

The same setup checks every change. Before a prompt change merges, an agent runs the old and new versions on a fresh sample of real requests and compares the outputs. A recent Sourcing change was checked against over 1,000 real requests this way.

Rook builds the harness

Rook didn't just inspire the harness. It builds it, with us making the calls.

When we wanted agents to remember their work between visits, so a user could pick up a search weeks later, I described what I wanted in Slack. Rook's sub-agents worked out how each agent stores its files, built snapshot and restore into the shared library, and opened a single PR that covered every agent. Review agents checked the exact commit and sent it back with fixes before it reached me.

Rook also keeps the agents healthy. Every agent has a report-issue script that writes an anonymized report to a database whenever something goes wrong, from a customer outcome that looks off to a sandbox that misbehaved. Each day, Rook scans those issues, watches the user sessions where they happened, and proposes fixes as PRs ready for us to review.

This is what makes owning a harness cheap, and it changes the job. When agents write most of the code and a new agent takes two hours to stand up, what's left is judgment: what belongs in the harness versus a single agent, what an agent should do with a vague brief, which failures actually matter to customers.

That's why we're a product team. Everyone decides what's worth building and owns it all the way to the customer: shipping it, telling customers about it, updating the docs and reading the feedback. The question stops being "can we build it?" and becomes "should we?"

Thanks to Keir for building the first version of Rook, to Eddie for turning it into the shared harness every agent runs on, and to Rook for building every version of Rook since.

We're hiring product people in London and San Francisco. If this sounds like your kind of problem, check out m.careers.