Inspiration

I run more than twenty projects with AI coding agents. They push all day, and every push ran the full CI suite again. My GitHub Actions bill hit $370 in July and $402 in August. The agents made me faster, and CI made me pay for it twice.

Every team adopting coding agents is heading for the same wall: more pushes, the same checks run over and over, and a bill that grows with every commit. Deleting tests is not the answer. Cutting the waste is.

What it does

Cirujano (Spanish for surgeon) operates on CI that works but costs too much. Its sibling entry, Sutura, is the nurse for CI that breaks. The developer is the doctor who signs off on both.

  1. Diagnose. Cirujano reads GitHub Actions billing and run history and ranks where the minutes go.
  2. Prescribe. NVIDIA Nemotron on Nebius Token Factory proposes one bounded, supported cut, or abstains when nothing is safe.
  3. Prove. Cirujano builds the patch itself, verifies it in Nebius Token Factory Sandboxes with the network off, then measures it on real runs.
  4. Ship. It opens a pull request with before and after minutes. A developer approves it. Cirujano never auto-merges.
  5. Relocate. Heavy work that can't be cut moves to on-demand Nebius AI Cloud VMs. The controller creates a VM when a job queues, then drains, stops and deletes it when idle, under explicit permits and cost caps.

The results so far

  • v0.3.0 is released, with a test build anyone can run in a minute. The tagged release passed 2,177 automated tests and CodeQL in release CI. It ships a prebuilt CLI that needs only Node and no credentials: one npx command measures a real public run (steps in the release notes). v0.3.0 also lets developers search the workflow source behind any recorded run, next to advisory commands that rank retained CI evidence.
  • −67% runner-minutes on merged pushes. On the public proof, each eligible merge push dropped from 3 billed minutes to 1, and every pull request check was kept.
  • 129 Sandbox scenarios, zero mismatches before the guard ever touched a real run.
  • A whole optimization decision for $0.00012: one Nemotron call, 1,115 tokens.
  • 880 observed CI jobs on Nebius, with complete job timing. The October 27 refresh records 3,660 job-minutes across 8 repositories since September 13. The October 24 video shows a real cycle: VM created, job run, VM deleted, 14 minutes end to end.
  • About 61% fewer private-repository CI minutes in the latest full week. GitHub billing records show 833 minutes a day for October 20–26, against 2,109 a day in July–August. At the observed list prices, those usage rates correspond to about $150 versus $380 over 30 days.
  • It knows when to say no. When an earlier idea, dependency caching, measured 3 minutes against 3, Cirujano opened no pull request. Every cut it ships has receipts.

How I built it

  • TypeScript 6 / Node 22.13+ monorepo with a core library, a CLI and a GitHub Action, tested with Vitest and bundled with esbuild.
  • NVIDIA Nemotron 3 Nano 30B A3B through the OpenAI-compatible Nebius Token Factory API, with grammar-constrained JSON output. The model chooses from a closed set of operations. It never writes YAML.
  • A deterministic workflow classifier and patch builder turn the model's choice into a minimal, reviewable diff that preserves what the workflow means.
  • Nebius Token Factory Sandboxes run a push-guard harness in disposable, network-disabled images built server-side, across a 69-cell guard matrix and 60 classifier cases.
  • Billing truth from job timestamps. GitHub's run timing endpoint reports zero, so Cirujano rebuilds billable minutes per job, rounded up the way GitHub bills.
  • On-demand runner controller. A small control loop watches the queue, creates a Nebius AI Cloud VM with cloud-init, registers a one-job GitHub runner, then drains, stops and deletes it when idle. Every controller works under a signed permit with a cost cap.

Challenges I ran into

  • The billing data lied. /actions/runs/{id}/timing returns total_ms: 0 on current GitHub, so I rebuilt cost from per-job start and end times.
  • Making a cheap change safe. The merge-run guard skips work only when that exact tree already passed its pull request. Any missing proof, error or timeout means every job runs.
  • Constrained decoding quirks. The Nemotron grammar rejected uniqueItems, and enum arrays could loop until maxItems, so I redesigned the schema around them.

Accomplishments that I'm proud of

  • A published v0.3.0 release that anyone can try in a minute, with no credentials and no setup beyond Node.
  • An optimizer that is allowed to say no, with abstention and no-improvement outcomes built in.
  • A real cut with receipts, proven twice: first in Sandboxes, then on real billed runs.
  • A real fleet: 880 observed CI jobs on on-demand Nebius runners across eight repositories.

What I learned

  • Most CI waste is re-verification, not slow tests.
  • A model choosing among safe operations, plus a deterministic builder, beats a model writing config.
  • Measure in billed, rounded minutes. Seconds saved don't always mean dollars saved.

What's next for Cirujano

Every team shipping with AI agents should get CI that finds its own waste, proves every cut and runs heavy work only when it's needed: more software on the same budget.

  • Make the released Action and CLI easier to adopt: a ranked waste report first, then explicitly permitted, verified pull requests.
  • More cut families: path filters, right-sized test shards, and duplicate push and pull request runs.
  • Pack heavy jobs onto shared Nebius VMs. My model shows about $120 a month net for my own fleet.
  • Join up with Sutura: one loop that heals red CI and trims green CI, with the developer approving every change.

Built With

  • cloud-init
  • esbuild
  • github-actions
  • github-cli
  • github-rest-api
  • nebius-ai-cloud
  • nebius-token-factory
  • nebius-token-factory-sandboxes
  • node.js
  • nvidia-nemotron
  • pnpm
  • typescript
  • vitest
  • yaml
Share this project:

Updates

Submission history