Incremental CI for AI agents

Your agents are waiting on tests that already passed.

Cutset is self-hosted CI for teams where agents write most of the code. Edit one function and get results from the 8 tests it affects in 40 seconds, instead of rerunning all 5,000 in 23 minutes.

agent-7 · acme/payments · edited ledger/rounding.got+00:00
Push-and-wait CIworking
$ git commit -am "Fix rounding" && git push
Cutsetworking
$ cutset verify

Same agent. Same edit. Same bug.  

Illustrative run. Cutset isn't released yet, so these times are modeled, not measured.

Keeps GitHub Actions

.github/workflows/ci.yml

steps:
- uses: actions/checkout@v7
- run: cutset verify

One step. Or install the GitHub App and skip Actions entirely.

One binary, one dev box

terminal

$ cutset init --plan
$ cutset verify
$ cutset up # later: a shared fleet

No account, no root, no cloud credentials to start.

No machines of your own?

site.toml

[pools.aws]
adapter = "aws-asg"
[costs]
overall-cap = { usd = 500 }

Start with an AWS pool and a hard spending cap.

The cost of waiting

2:47 pm at a team running 40 agents.

Nobody here is idle on purpose. Every agent is doing what its pipeline lets it do.

  • #1
    3m
  • #2
    code
  • #3
    debug
  • #4
    24m
  • #5
    9m
  • #6
    16m
  • #7
    23m
  • #8
    8m
  • #9
    15m
  • #10
    22m
  • #11
    7m
  • #12
    code
  • #13
    debug
  • #14
    6m
  • #15
    13m
  • #16
    20m
  • #17
    5m
  • #18
    12m
  • #19
    19m
  • #20
    4m
  • #21
    11m
  • #22
    code
  • #23
    debug
  • #24
    10m
  • #25
    17m
  • #26
    24m
  • #27
    9m
  • #28
    16m
  • #29
    23m
  • #30
    8m
  • #31
    15m
  • #32
    code
  • #33
    code
  • #34
    debug
  • #35
    21m
  • #36
    6m
  • #37
    13m
  • #38
    20m
  • #39
    5m
  • #40
    12m
  • waiting on CI · 31
  • chasing a known failure · 4
  • writing code · 5
14 dev boxes, 6 rented servers: 18% busy
  1. An agent edits one line and waits for all 5,000 tests.See the fix ↓
  2. A test already passed on agent-7's dev box. CI runs it again anyway.See the fix ↓
  3. Twelve agents rebase onto the same main and run the same suite twelve times.See the fix ↓
  4. Your 20 machines sit 18% busy while the hosted CI bill hits $9,400.See the fix ↓
  5. 4 agents debug TestLedgerRollup. It has been broken on main since 11:02.See the fix ↓
  6. 27 PRs wait in the merge queue. The last one lands at 5:47 pm.See the fix ↓

At 2:47 pm, 5 of your 40 agents are writing code. The other 35 are waiting, or chasing a failure that isn't theirs.

How it works

Reuse what's still true. Run what isn't.

Every result is tied to the exact code, toolchain, and environment that produced it. Change one function and only the tests that depend on it run again.

  1. 01

    Snapshot

    Captures the change, including uncommitted edits. No commit, no push.

  2. 02

    Map

    Learns what each test depends on from your build graph and from watching tests run.

  3. 03

    Reuse

    A test whose inputs haven't changed keeps its result. Work already running is joined, not repeated.

  4. 04

    Run the rest

    Sends the remaining tests to whichever machine finishes them soonest.

acme/payments · 5,000 tests · each dot ≈ 14 tests

run 8 · reused 4,992

api
auth
billing
checkout
disputes
fx
ledger
payouts
refunds
reports
tax
webhooks

Edited ledger/rounding.go. Only the tests that depend on ledger.Round run.

cutset explain last
$ cutset explain last
agent-7 · ledger/rounding.go changed
8 tests use ledger.Round ran
4,992 tests, inputs unchanged reused

Agents call Cutset from the shell and get structured answers. A quick partial run gives fast feedback, but only a full verify can turn a required check green.

Before Cutset skips anything on your repo

0 / 50 matches in a row

full suite 5,000 tests · 1 failed
Cutset's pick 8 tests · same 1 failed ✓

Every change runs the full suite and Cutset's pick side by side. You get full-suite results the whole time.

Results that travel

A test that passed on a dev box counts in CI.

Each result records the exact code, toolchain, and platform it ran with. If an enrolled machine already passed a test on those inputs, CI accepts the result instead of running it again.

1 · on devbox-04

agent-7 · devbox-04
$ cutset verify
✓ all required checks · 8 run
recorded: a41f9c2 + 1 file · go 1.26

2 · push

agent-7 · devbox-04
$ git push
same code, same toolchain, same platform
nothing left to run

3 · the PR

All checks passed13 s after push
✓

cutset/required

0 run · 5,000 passed on devbox-04 (enrolled dev box)

Which results count is your call

  • ✓devbox-04 · enrolled dev box · counts toward required checks
  • ✓ci-ovh-02 · your server · counts toward required checks
  • –a laptop that isn't enrolled · a hint only; CI runs the tests
  • –a fork PR from an outside contributor · waits for a maintainer to approve the commit

No repeated work

Twelve agents asked. It ran once.

When main moves, every agent rebases and asks the same question. Cutset runs the shared part once and sends the answer to all of them.

main → 7e3b1d0requested 0 · ran 1 · joined 0
  • agent-3…
  • agent-7…
  • agent-12…
  • agent-5…
  • agent-19…
  • agent-22…
  • agent-8…
  • agent-31…
  • agent-14…
  • agent-26…
  • agent-2…
  • agent-37…

main changed ledger and billing · 347 tests cover that change · 1:50

12 agents rebased onto the same main. One run answers all of them. Each agent's own edits still run separately.

Your machines first

Use the machines you already pay for. Burst only when it's faster.

Dev boxes and rented servers cost the same whether they're busy or not. Cutset fills them first, and launches AWS capacity only when waiting would take longer, inside a cap you set.

task billing integration shard · required

ci-ovh-02 · your server, already paid fordone 0:40 · chosen

free in 0:10 + run 0:30 · no added cost

new AWS instance · launched as neededdone 1:35

boot 1:00 + prep 0:15 + run 0:20

Order: 1 · the machine that asked → 2 · your other machines → 3 · AWS, only when your machines would make the work wait longer than 2 min (agent work) or 30 s (required checks). Cutset compares finish times, not instance prices.

$1,120 of $1,500 this month

on-demand spendalert 80% · last 25% kept for required checks
  • New work falls back to your machines.
  • Running work is never stopped.
  • No check passes because money ran out.

Fleet advisor

Stop guessing which machines to buy.

Cutset knows what your jobs actually need: cores, memory, disk, and when. It replays your real workload against the machines you are considering and shows what each one buys you, before you spend anything.

cutset fleet advise --budget 600/mo
$ cutset fleet advise --budget 600/mo
workload last 4 weeks · 40 agents · 3 host classes
bottleneck memory: 38% of admission waits are for RAM
critical path: mostly single-threaded tsc
1. +64 GiB on 4 shared boxes
+$120/mo · p95 green 9:40 → 5:50
2. RAM + AWS burst +$540/mo · p95 4:20
3. +1 32-core server +$310/mo · p95 8:55
more cores barely help: type checks don't parallelize
confidence backtest error 8%
weakest: no history on 32-core EPYC
measure it first: cutset fleet probe (~$3)
What each option buys youreplayed on your last 4 weeks of jobs
0:002:004:006:008:0010:00+$0/mo+$200/mo+$400/mo+$600/moextra monthly costp95 time to green (lower is faster)Current fleet: +$0/month, p95 9:40 (9:20 to 10:00)Current fleet+64 GiB on 4 shared boxes: +$120/month, p95 5:50 (5:20 to 6:25)+64 GiB on 4 shared boxes · recommended+1 32-core server: +$310/month, p95 8:55 (8:25 to 9:25)+1 32-core serverAWS burst only: +$420/month, p95 6:30 (5:50 to 7:20)AWS burst onlyRAM + AWS burst: +$540/month, p95 4:20 (3:55 to 4:50)RAM + AWS burst

Bars show the confidence range. Backtested against what actually happened on your fleet: within 8%.

Known failures

Stop sending agents after failures you already know about.

Cutset keeps every pass and failure with the conditions it ran under. Agents ask whether a failure is new, already broken on main, or flaky, and get evidence back instead of a guess.

Without history · agent-120 min
PR #4190 · hides the flake instead of fixing it
With Cutset · agent-12 · 1 min
$ cutset history TestRefundWebhook
main, 14 days: 186 real runs · 7 failed
all 7 failures ran with 8+ tests in parallel
first seen Oct 25 · last seen today 13:52
investigation: acme/payments#4182 (agent-3, open, updated 2h ago)
$ cutset verify --only 'TestRefundWebhook'
✓ passed · only covers TestRefundWebhook

agent-12: Suspected flake, tracked in #4182. Not caused by this change. Continuing.

✓cutset/required · before merge, Cutset reran TestRefundWebhook: passed on attempt 2, both attempts recorded on #4182
Broken on main
$ cutset verify
✗ TestLedgerRollup ledger/rollup_test.go:142
also fails on base 9c1e2a0 with the same error (first seen 11:02)
required checks stay red until it's fixed or policy allows an exception
webhook sent to your repair agent · 3 other agents stop debugging and keep working

Merge queues

A merge queue that keeps up with 40 agents.

Most merge queues run the full suite on every batch, even when two PRs touch different packages. Cutset reruns only what the combination can affect, so the queue stays cheap enough to leave on.

Full suite on every merge batch · 19 minsustains 9 PRs/hour
102030PRs waiting to merge12:00 pm · 10 PRs in the queue12:15 pm · 13 PRs in the queue12:30 pm · 13 PRs in the queue12:45 pm · 15 PRs in the queue1:00 pm · 17 PRs in the queue1:15 pm · 19 PRs in the queue1:30 pm · 20 PRs in the queue1:45 pm · 22 PRs in the queue2:00 pm · 24 PRs in the queue2:15 pm · 26 PRs in the queue2:30 pm · 27 PRs in the queue2:45 pm · 24 PRs in the queue3:00 pm · 24 PRs in the queue3:15 pm · 22 PRs in the queue3:30 pm · 20 PRs in the queue3:45 pm · 19 PRs in the queue4:00 pm · 18 PRs in the queue4:15 pm · 17 PRs in the queue4:30 pm · 14 PRs in the queue4:45 pm · 12 PRs in the queue5:00 pm · 10 PRs in the queue5:15 pm · 8 PRs in the queue5:30 pm · 5 PRs in the queue5:45 pm · 3 PRs in the queue27 at 2:4712 pm2 pm4 pm6 pm
Cutset on every merge batch · 2:10sustains 48 PRs/hour
102030PRs waiting to merge12:00 pm · 1 PRs in the queue12:15 pm · 1 PRs in the queue12:30 pm · 1 PRs in the queue12:45 pm · 1 PRs in the queue1:00 pm · 1 PRs in the queue1:15 pm · 1 PRs in the queue1:30 pm · 1 PRs in the queue1:45 pm · 1 PRs in the queue2:00 pm · 1 PRs in the queue2:15 pm · 1 PRs in the queue2:30 pm · 1 PRs in the queue2:45 pm · 1 PRs in the queue3:00 pm · 1 PRs in the queue3:15 pm · 1 PRs in the queue3:30 pm · 1 PRs in the queue3:45 pm · 1 PRs in the queue4:00 pm · 1 PRs in the queue4:15 pm · 1 PRs in the queue4:30 pm · 0 PRs in the queue4:45 pm · 0 PRs in the queue5:00 pm · 0 PRs in the queue5:15 pm · 0 PRs in the queue5:30 pm · 0 PRs in the queue5:45 pm · 0 PRs in the queueEach batch done in 2:10. Nothing piles up.12 pm2 pm4 pm6 pm

#881 (ledger) + #884 (checkout UI): 212 tests affected by the combination · 4,788 reused from each PR's own run

The math

Same team, same agents, five times the answers.

One modeled day for a team with 40 agents, a 5,000-test repository, 14 dev boxes, and 6 rented servers.

  • #1
    3m
  • #2
    code
  • #3
    debug
  • #4
    24m
  • #5
    9m
  • #6
    16m
  • #7
    23m
  • #8
    8m
  • #9
    15m
  • #10
    22m
  • #11
    7m
  • #12
    code
  • #13
    debug
  • #14
    6m
  • #15
    13m
  • #16
    20m
  • #17
    5m
  • #18
    12m
  • #19
    19m
  • #20
    4m
  • #21
    11m
  • #22
    code
  • #23
    debug
  • #24
    10m
  • #25
    17m
  • #26
    24m
  • #27
    9m
  • #28
    16m
  • #29
    23m
  • #30
    8m
  • #31
    15m
  • #32
    code
  • #33
    code
  • #34
    debug
  • #35
    21m
  • #36
    6m
  • #37
    13m
  • #38
    20m
  • #39
    5m
  • #40
    12m
  • waiting on CI · 31
  • chasing a known failure · 4
  • writing code · 5
14 dev boxes, 6 rented servers: 18% busy
MeasurePush-and-wait CICutset
First answer after an edit23 min40 s
Minutes blocked per agent per hour469
Answers per hour, 40 agents80400
Test executions per hour400,00024,000
Merge queue sustains9 PRs/hour48 PRs/hour
Queue at 2:47 pm27 PRs1 PR
Time lost to a known flake69 min1 min
Your own machines busy18%64%
Changes verified per month2,64013,200
Cloud CI spend per month$9,400$1,120 (cap $1,500)
Cloud cost per verified change$3.56$0.08

Machines you already own or rent cost the same either way and are left out of the cost rows.

cutset stats --window 24h
$ cutset stats --window 24h
requests 3,212 verify · 10 per agent-hour
tests 192,000 run · 15,868,000 reused
412 requests joined a run already going
push→green p50 0:52 · p95 4:10
agents blocked 9 min/hour (median)
changes 440 verified · $0.08 each

These are the numbers Cutset reports about your own fleet, so the table above stops being a model.

Yours to run

One binary. Your machines. Your rules.

Cutset never…

  • ×reuses a result it can't tie to the same inputs.
  • ×passes a check because the budget ran out.
  • ×stops running work to save money.
  • ×runs fork code on your dev boxes.

Starts on one dev box

cutset init --plan, then cutset verify. No root, no cloud credentials, no GitHub App, no account. The same setup grows into a fleet with a small always-on coordinator.

No vendor compute

Dev boxes, OVH servers, EC2, or any Linux machine that can reach your coordinator. AWS Auto Scaling groups when you need more.

Trust you control

You choose which machines' results count. A PR can't remove its own required checks. Untrusted code never writes the shared cache.

Fork PRs, safely

A maintainer approves the exact commit first, or fork PRs run in Firecracker microVMs on a separate pool with their own budget.

Source available

FSL-1.1-ALv2. Use it, change it, run it for your company; just don't sell it as a competing service. Every release becomes Apache-2.0 after two years.

Early access

Get your agents out of the queue.

46 min

of every agent-hour spent waiting on CI today

9 min

with Cutset, on the same team and machines

Cutset is in development. Early-access teams get the first builds and help shape the defaults. Free to run on your own machines.

We'll only email you about Cutset. One click to leave.