Undercut for Jules

Jules already reads AGENTS.md. Give it one that stops overpaying.

Undercut is a free, MIT-licensed routing policy you drop into the root AGENTS.md that Jules — Google's autonomous, cloud-VM coding agent — already reads on every task — cheap tier first, escalate only on evidence, never on a vibe. Jules has no built-in cost dial of its own to compare against; this exists because the same overpay-by-default pattern we measured elsewhere in the agent ecosystem (see the Claude Code page) shows up anywhere an agent defaults every task to its strongest model.

Install for Jules See the benchmarks
Works anywhere a routing policy can be read
Claude Code Codex Cursor Copilot OpenCode Jules

How this maps onto Jules

No skills directory. AGENTS.md is the whole mechanism.

Jules doesn't have a "skills" directory the way Claude Code does, and it isn't listed as a supported target on skills.sh either — there's nothing that auto-discovers skills/firstpass/SKILL.md on its own. What Jules does read automatically, per Jules's own getting-started docs, is a single root-level AGENTS.md: "Jules now automatically looks for a file named AGENTS.md in the root of your repository," used to help Jules "generate more relevant plans and completions." Jules's environment setup docs add that for simple projects without an explicit setup script, Jules also "refer[s] to agents.md or your readme.md file for hints to setup an environment on the fly." That's the entire documented surface — no .jules/ config directory, no per-user global file, no nested-file precedence rule. Undercut's policy has to be delivered as plain text inside that one file — see Install below for the exact mechanics.

The tier names — cheap, standard, frontier, apex — stay generic on purpose. models.md gives the rule of thumb rather than a fixed slug for Jules specifically: Jules runs on Google's own Gemini models rather than exposing a picker across vendors, so cheap resolves to the smallest/fastest model in Google's current Gemini lineup that Jules has access to, standard to its default working model, frontier to the highest-reasoning production model, and apex to a single batched tie-break call on the strongest one available. Nothing here sits between Jules and its model backend — it's instruction text Jules reads out of the repo at task time, no proxy, no network hop.

Install for Jules

Free. MIT. Nothing installs, nothing proxies your traffic.

Append it to AGENTS.md (the only path)

A root-level AGENTS.md is read in full by Jules on every task in the repo — so appending the policy text there is the only reliable way to get it in front of Jules, since it doesn't depend on Jules separately choosing to open another file, and there's no per-user or per-workspace equivalent to fall back to.

$ echo "" >> AGENTS.md && curl -fsSL https://raw.githubusercontent.com/undercutsh/firstpass/main/skills/firstpass/SKILL.md >> AGENTS.md

If the repo has no AGENTS.md yet, the same command creates one. Already run this policy through Codex, Copilot, or another AGENTS.md-reading client in the same repo? Jules reads the same file — nothing extra to install.

Not on skills.sh. Jules isn't one of the listed npx skills add targets as of this writing, and Jules has no documented Agent Skills / SKILL.md discovery mechanism at all — only AGENTS.md, confirmed against Jules's own docs. The command above is the whole install.

Validate it yourself

  1. 1Read the published results — testing/README.md and the raw JSON in testing/results/
  2. 2Reproduce for free, no API key, no spend: node src/main.js --mock
  3. 3Kick off a small Jules task against a repo with the policy installed and check its plan/output for which tier it names before starting mechanical work

Zero lock-in. It's instruction text Jules reads — delete the block and you're back to status quo.

How it works

The Undercut Rubric · v1

Six flags assign a tier. Three triggers are the only way up.

This is a named, versioned spec — not internal logic we could quietly change. When the rubric changes (a new flag, a different cap), the version number moves and the changelog says why.

Every unit of work gets scored against six flags, then assigned the cheapest tier that can plausibly handle it. It only moves up a tier when something objective proves it needs to — a failed check, a measured disagreement, an explicit uncertainty flag. It never moves up on a guess, and it never moves back down mid-task.

unit of work
6-flag rubric
0 flags
cheap~90% of units land here ✓
1–2
standard
3+/own
frontier
↑ escalate +1 tier only on: fail ×2 · two runs disagree · tagged "uncertain" residue only — never redoes the batch
See the rubric

Step 1 — Base tier, six-flag rubric

Unverifiable — can output be checked mechanically? (tests, schema, diff, grep)
Ambiguous — one right answer, or several defensible ones?
Blast — reversible? touches money, auth, user data, production, deletes?
Cross-cutting — one file/source, or reasoning across many?
Novel — pattern-following, or genuinely new design?
Format-strict — must output match an exact schema?

0 flags → cheap · 1–2 → standard · 3+ or any ownership/judgment call → frontier. Apex only when you can write one sentence stating why the marginal intelligence pays for the cost.

The override — single biggest lever

Cheap-to-verify ⇒ cheap-to-generate. If output can be checked mechanically, it starts at the lowest tier regardless of how hard it looks — verification catches failure. Only unverifiable work needs to start high.

Step 2 — Escalate exactly one tier, on evidence only

  • Verification fails twice at the current tier
  • Two cheap-tier runs disagree on ambiguous-flagged work
  • The worker tags an item "uncertain"

Residue-only handoff

The next tier up gets only the failed or uncertain items, plus verification notes. It resolves the residue — it never redoes the batch.

Hysteresis — guardrails

Never de-escalate mid-task. Max one retry per tier. Anything still unresolved goes to a single batched apex tie-break call. One hard file in a 700-file job doesn't drag the other 699 up a tier.

 unit of work
      |
  6-flag rubric
      |
  +---+----+
  | 0 flags|--> cheap
  | 1-2    |--> standard
  | 3+/own |--> frontier
  +---+----+
      | fail x2 / disagree / uncertain
      v
  escalate +1 tier
  (residue only)
      |
  still unresolved?
      v
  single batched
  apex tie-break

Why it holds up

Flags steer. Verification and escalation decide.

Even when the rubric flags are scored imperfectly, the escalator still routes work to the right tier almost every time — because a wrong flag only ever costs one extra cheap attempt, never a wrong answer or a big bill.

See the data

A stock dispatcher model reproduces the rubric flags imperfectly — Haiku hits 90% agreement, Sonnet 93%. The weakest flag (format-strict) is only 60%. None of that matters: under the shipped policy, both dispatchers still route 100% of units to the correct tier. A wrong flag changes the ladder cap, never the base tier — worst case, one extra cheap attempt.

Haiku dispatcher
90% flag agreement
100% tier-match
Sonnet dispatcher
93% flag agreement
100% tier-match

The rules are about the work, not the model.

Every rule is a property of the unit of work — verifiable, ambiguous, blast-radius — never a specific model's known weakness. Vendor cards go stale as models change; work properties don't. It's also hard-won — a format-strict rule that worked on Anthropic backfired on Gemini, which is exactly why the rubric no longer encodes per-vendor behavior.

Honest limits

What this doesn't do.

Not a proxy, not a gateway, doesn't auto-flag in production — and on Jules specifically, it's not a "skill" Jules discovers on its own: it only takes effect if you've put it in the root AGENTS.md that Jules reads (see Install above), and it's not listed on skills.sh as an install target. Jules's own reliability at scoring the flags hasn't been separately measured the way Claude Code's has (see above); treat that as unverified until tested. It doesn't promise a dollar figure for your workload, and because Jules runs each task in an isolated cloud VM rather than a session you watch live, there's no interactive way to confirm mid-run which tier it picked — only after the fact, from its plan or output. Full list of general limits, with the finance/procurement note and the paid-tier disclosure, is on the main page.

Undercut the top tier. Not the quality bar.

Nothing about this page expires. What does keep happening is the token bill, one async task at a time, on whatever Jules is currently doing with mechanical work.

View on GitHub