Lesson 35 of 36
How Warp improves its own factory
On this page
A platform team copied the visible half of an agent factory. They took the dashboard (autonomy, cycle time, cost per PR), pointed a nightly job at the review agent's prompt, and let the job open a pull request whenever the review agent missed something. Nobody measured the review agent first. The job read a handful of misses, rewrote the prompt, and a teammate approved each change because the diff read well. Three weeks in, the review agent began approving migration PRs it used to block: one rewrite had softened a rule that a single noisy miss made look excessive. A bad migration reached production on a Friday and cost a weekend of rollback. The dashboard showed autonomy rising the whole time. This is a composite, not a reported incident: no judge, an editor trusting the missing judge, and a reviewer who saw only the diff. Decide now: which part of a vendor's improvement stack do you copy first, and what evidence must exist before anything may rewrite a prompt?
You build factory/adopt/warp.md — a fill-in plan that borrows Warp's improvement stack: scorer, self-improvement run, memory store and router, each with your own threshold, reviewer and test. It serves the Prove stage of this course's loop (Slice → Gate → Run → Wrap → Prove): Prove decides whether the line earned autonomy, and this file decides which of Warp's published mechanics may spend that evidence to change the line itself, and which you refuse. Warp's docs publish the mechanics in detail and almost no results, which separates what you can copy from what you must produce.
What is actually going on
Warp's factory has a measuring half and an acting half, and the docs describe both. The measuring half is the scorer: an LLM-based eval that checks whether completed runs from selected agents meet criteria you define. It assigns a classification, not a numeric grade, and its fields are the agents to evaluate, judge instructions, a judge model, classifications each with a score, a pass threshold and a sample rate (Warp docs, first-party, observed 2026-10-29). The acting half is the self-improvement run. A failure is a score under the pass threshold. By default, once an agent has 25 distinct unreviewed failures, or its oldest unreviewed failure is seven days old, the run groups that agent's failures into a follow-up run that proposes a fix, and the count is configurable from 1 to 50 (first-party). When the factory is defined as code, that follow-up can open a pull request against the factory definition itself, changing prompts, skills and configuration (first-party).
Two more parts sit beside that loop. Memory writes durable facts after a conversation ends and retrieves them in the background in later runs (first-party). A router picks the model per task (first-party), and benchmarks compare configurations on fixed tasks before a live change (first-party).
Read the stack as one loop with one load-bearing part. Every arrow after the scorer inherits the scorer's errors: a wrong judge fills the queue wrongly, the proposal fixes the wrong thing, and the reviewer approves a diff that reads well. The docs publish no scorer pass rates or judge accuracy, so the polish shows how the stack is wired, not how well it works. The wiring is free to copy. The evidence is yours to produce, which gives the line the whole stack turns on: Adopt the judge before the editor.
In the diagram, look for the one node that every later arrow depends on.
It showed one measuring node and one human node: nothing between them corrects a wrong classification, so the reviewer needs the failed runs, not only the diff.
The console is worth one paragraph of its own, because it is where the governance is visible. In the demo, a scorer's configuration page was read-only with a banner saying the scorer is managed in a repository and changes belong in that repository at a named ref (observed in a public demo, 2026-10-29 frame at 24:40). That single banner is the whole Lesson 06 argument in shipped form: the thing that grades the agents cannot be edited from the surface the agents' work is watched on. The same sidebar held the factory's scorers, its self-improvement queue with an unread count, and its benchmarks, and the factory on screen was one of two the team runs.
The rule and its condition
Adopt Warp's stack in dependency order, and adopt a layer only when you can already produce the evidence that layer spends. Adopt the scorer when an agent already produces runs you can sample. Adopt the improvement run when failures cluster faster than a person can read them and a named person reviews each proposal. Adopt memory when facts are re-derived across runs and each memory traces to its source run. Adopt the router when you own a benchmark built from your tasks. Otherwise refuse that layer and write down why. The table gives Warp's published position on seven fixed rows; the last column is what you must state before the row is yours. Lesson 9, Score the Repo Before You Switch Autonomy On, applies the same idea to the repo.
| Dimension | Warp, as published | You must state before it is yours |
|---|---|---|
| Trigger | Work arrives from Slack, Teams, GitHub, GitLab, Azure DevOps, Linear, Jira, a schedule or a webhook (first-party). Improvement fires on 25 distinct unreviewed scorer failures or a seven-day-old oldest one, configurable 1 to 50 (first-party). | Your sources, and a failure threshold set from your own failure volume. |
| Where the agent works | A factory is a team of cloud agents connected to your repositories (first-party); harnesses include the Warp Agent, Claude Code and Codex (first-party). Runs execute on vendor-hosted compute by default, and enterprise teams can keep checkout and execution on their own infrastructure; a live demo shows a hosted runner per agent with a self-hosted option in the agent's settings (first-party; observed in a public demo, 2026-10-29 frame at 26:41). | Where code is checked out and executed, confirmed with the vendor before adoption. |
| Gates before merge | The factory never merges for you; repository permissions and branch protection decide, and spec approval is a foreman instruction, not a repository permission (first-party). Review runs on a different model or harness from implement (first-party). Scorers classify sampled completed runs (first-party); benchmarks compare configurations before a live change (first-party). | Required checks in branch protection, a scorer on the reviewer, a benchmark before any config change. |
| Who approves the merge | Humans, through repository permissions (first-party). For improvement PRs, reviewerType is admins (default), team, none or custom with reviewerEmails, and one eligible reviewer is requested at random unless none (first-party). | A named person per lane, enforced by a required-reviewer rule, not by the request. |
| After merge | A dashboard of autonomy, median PR cycle time and median cost per PR, plus the three newest self-improvement PRs (first-party). Autonomy is defined as the share of merged PRs that needed no human code push, and cost per PR is a comparison metric, not a billing figure (first-party). Memory is written and merged asynchronously after conversations end (first-party). | The outcome measures you trust (Lesson 14, Measure Outcomes, Not the Share of AI Code). |
| Scale claim (self-reported) | On a public live demo of one internal factory, the last thirty days showed autonomy at 75% (323 of 429 observed factory PRs), 778 merged PRs of which 487 came from that factory, a median 5.7 hours from kickoff to merge (kickoff to PR 29 minutes, PR to first human review 2.2 hours, first review to merge 20 minutes), and a median cost per PR near $38 against roughly $120,384 of attributed cost across 1,711 PRs, split into compute, platform and inference. The two readings I took minutes apart moved (776 to 778 merged), so these are live figures from one observed demo, not an audited report, and the dashboard labels its own cost total approximate (observed in a public demo, 2026-10-29 frames at 8:30 and 27:40). The same team also reported, with no figures, that UI tasks ran well on one model in an internal comparison, and that a later run used five memories and was faster (vendor-claim, no figures published). | Nothing to copy. Treat every one of these as a hypothesis with a task distribution you do not have. |
| What the company has not published | In the pages read on 2026-10-29 and the demo watched: how a scorer's judge was validated and what its pass rate is, benchmark suite contents and per-class results, the agent-authored share of code, measured savings from memory reuse, how often self-improvement proposals are accepted, how the improvement runs themselves are charged, and how "observed factory PRs" is defined across more than one factory. The cost total is labelled approximate by the product itself (first-party). | Your own numbers for each of these, kept from week one. |
The tree applies the rule when you have more than two options at each step.
Worked case
A four-person team runs agents on one monorepo with three risk lanes (Lesson 7, Risk Lanes). Lane A is docs and config, lane B is application code, lane C is database migrations and auth. A review agent exists but runs on the same model as the implementer, and nothing scores it. The factory definition lives in the repo and changes go through pull requests (Lesson 6, Protect the Files That Govern the Agent).
Option one: switch the stack on in the order it is easiest to see: dashboard, router, memory, self-improvement. Option two: fill a mechanics table with a lane, a local version, a status and a one-week test per row. Decide now: for which lane and mechanic do you write refuse, and which test gates each row?
The reveal is option two, and the table is the plan.
| Mechanic | Lane | My version | Status | My test (one week) |
|---|---|---|---|---|
| Scorer with sample rate | B | Judge on the review agent, three classifications, sample rate 50% | adopt | Seed 10 PRs with known defects; judge must flag at least 8 before the sample rate matters |
| Failure-cluster threshold | B | failedRunThreshold 8; treat the age clause as the real cadence | adapt | Two weeks of scorer cards: if weekly failures stay under 3, keep improvement off |
| Reviewer type and random reviewer | B, C | custom with two named emails in B, one named email in C | adapt | Dry-run a proposal; confirm the requested reviewer is on the list and branch protection blocks merge without them |
| Proposal as PR against the definition | B, C | Proposals may edit prompts and skills; scorer files are locked by branch protection | adapt (B), refuse (C) | A test proposal that edits scorer.md must be unmergeable |
| Per-store memory with traceability | A | One agent store, read-write, docs lane only | adapt (A), refuse (C) | Write one memory, confirm it names its source run, delete it, confirm the change is recorded |
| Retrieval reported per run | A, B | Each run output lists the memory ids it retrieved; I build this | adapt | Run one task with and without the store; the listed ids must match what changed |
| Different-model reviewer | B, C | Review agent on a different model or harness from implement | adopt | Re-run the 10 seeded PRs under both setups; compare defects caught |
| Router by task class, benchmark first | A | Docs tasks to a cheaper model; migrations pinned | adapt (A), refuse (C) | 10 own docs tasks with correctness criteria; at most 1 worse than baseline |
Illustrative composite. The numbers here are modeled, not measured, and are not Warp's defaults. Assume lane B produces 40 review runs a week, you sample 50%, and 20% of scored runs fail: 20 scored runs, about 4 failures a week. The default count of 25 would take over six weeks to fill, so the seven-day clause fires first and each proposal would rest on about 4 failures. At the default 10% sample rate the same lane yields 4 scored runs and under 1 failure a week.
That arithmetic is the point of the second row. At low volume the age clause, not the count, sets your cadence, so every proposal is a hypothesis from a handful of runs. Hence the named reviewer, the failed runs travelling with the proposal, and the benchmark re-run before merge. Hence also the scorer first: Adopt the judge before the editor. The docs I read confirm two knobs, sample rate and failedRunThreshold; check whether your plan lets you change the age clause.
Lane C gets refusals in three rows: it has the highest cost per wrong approval and the smallest failure volume, so it keeps pinned models, no automated proposals and no memory. Option one fails in order: the router saves money before any judge says whether quality held, memory stores facts from unscored runs, and self-improvement proposes edits a reviewer approves from the diff alone. That is the Friday failure again. The file you write is the table above as a template:
file: factory/adopt/warp.md
Scorer
agent: review (lanes B, C) judge model: <a model that is not the reviewer's> classifications: correct-call 1 | false-block 0 | missed-defect 0 pass threshold: 1 sample rate: 50% threshold: judge flags at least 8 of 10 seeded defects reviewer: <named person who owns the scorer file> test: seeded-PR run in week 1; a low count means rewrite the judge, enable nothing else
Self-improvement run
failedRunThreshold: 8 reviewerType: custom reviewerEmails: <two named people for lane B> lane C: no automated proposals threshold: at least 3 failures a week across two weeks, else keep off reviewer: <named person> sees the failed runs, not only the diff test: a proposal editing scorer.md cannot be merged
Memory store
store: agent store for the docs-lane implementer, read-write; lane C none threshold: a memory is kept only if it names its source run reviewer: <named person> reads store changes weekly test: run with and without the store; retrieved ids are listed per run
Router
rule: docs tasks to <cheaper model>; migrations pinned threshold: at most 1 of 10 own tasks worse than baseline, and cost lower reviewer: <named person> signs the benchmark comparison test: 10 own tasks with correctness criteria, run before the change
Faded case
Skip to the open case if this is familiar.
A repo has an implement agent and a review agent on the same model, work arriving from a chat thread, and no scorer, benchmark or memory. A manager asks you to turn on self-improvement and a cheaper auto-efficient router this week, because the cost line is visible (first-party).
| Candidate | Lane | Test it would run | Evidence it needs first |
|---|---|---|---|
| Scorer on the reviewer | B | Seeded defects, judge must flag most of them | Review runs to sample |
| Self-improvement run | B | Dry-run proposal that edits the scorer must fail to merge | A scorer producing failures |
| Memory store | A | Retrieved ids listed per run | Repeated facts, traceable writes |
| Router | A | 10 own tasks vs baseline | A benchmark and scorers |
Pick the one you adopt first, its starting sample rate, and why the other three wait. The scorer docs use 10% as their worked example (first-party).
Open case
A payments-adjacent repo is under change control. Any change to how software is reviewed needs a named, accountable approver recorded in the change ticket, and an approver cannot be picked at random from a group. The factory's review agent has a scorer, and failures cluster weekly. Self-improvement will open pull requests against the review agent's prompt in the factory definition. The compliance lead wants the improvement loop on with the audit trail intact. Write the reviewer configuration you would ship.
Where this breaks
Copying the polish without the evidence layer. The dashboard measures throughput: autonomy is the share of merged PRs that needed no human code push, and cost per PR is a median that splits each run's cost, child runs included, across its PRs (first-party). Neither says the PRs were right, and the cost of improvement runs is unpublished.
A vendor's internal finding does not transfer. "UI tasks run well on one model" was reported without scores, procedure or task distribution. The routing papers report savings on public benchmarks with the authors' own scoring (paper, RouteLLM), and RouterBench exists because routing quality depends on the task distribution (paper, RouterBench). Only a suite built from your tasks answers it.
Memory is not free. Warp states that memory creation and retrieval consume no tokens and add no latency to the active task (first-party). That covers the active task, not review load, stale memories, or a wrong memory superseding a right one. The Mem0 authors report more than 90% token savings against full context, on a conversational benchmark and by their own evaluation (paper), not on coding work. Claude Code's docs add that memory is context, not enforced configuration (first-party).
A memory written from a run that read untrusted text will be retrieved by later runs. The source record is your control.
Key Takeaways
- Copy the evidence layer before the dashboard; wiring tells you nothing about judge accuracy.
- Adopt the judge before the editor.
- Set the failure threshold from your own failure volume, not from Warp's default.
- Name the reviewer in config, then enforce that person with a required-reviewer rule.
- Benchmark your own task class before routing; a vendor's internal finding will not transfer.
- Refuse memory in the migration lane until each memory traces to a reviewed source.
What You Have Now
factory/adopt/warp.md — a fill-in plan that borrows Warp's improvement stack: scorer, self-improvement run, memory store and router, each with your own threshold, reviewer and test. It lives in your repo beside the factory definition, protected like any file that governs the agent, and it serves the Prove stage: it records which of Warp's mechanics earned autonomy in which lane, and which you refused. Lessons 28 to 31 go deeper on the parts this file selects among, and Loop Engineering's locked scorer is the rule behind the scorer-file row.
Further Reading
- Warp: Scorers: the fields and classification model behind the judge.
- Warp: Self-improvement: trigger,
failedRunThresholdandreviewerTypein full. - Warp: Benchmarks: suites, trials and comparing configurations before a live change.
- Warp: Custom routers: complexity-based and rule-based routing.
- Warp: Agent Memory: stores, access modes, traceability and auditability.
- RouterBench: why routing quality is measured against a task distribution.
Exercises
- Create
factory/adopt/warp.md — a fill-in plan that borrows Warp's improvement stack: scorer, self-improvement run, memory store and router, each with your own threshold, reviewer and testfor one repo, with all four sections and a status of adopt, adapt or refuse for each lane. - Run the seeded-defect test for your scorer and record how many of ten defects it flags; under your threshold, rewrite the judge first.
- Build a ten-task benchmark from last month's merged PRs in one task class and compare two model configurations on quality and cost. Record it in the Router test field.
Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in
Check your understanding
Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in