Skip to content
Rivet

Give it a GitHub issue. Get back a tested pull request.

Rivet is an autonomous software engineer. It plans a fix, writes the code in an isolated sandbox, runs the project's own tests, has a second agent review the change, and opens the pull request, recording every step along the way.

Open source under the MIT license. Runs on your own machine.

Prevent concurrent room double-booking

xuanhieu2611/rivet-demo-booking issue #1

Completed
  1. Provision
  2. Baseline
  3. Plan
  4. Implement
  5. Validate
  6. Review
  7. Publish
  1. 00:00Job created from issue #1
  2. 00:01Provision sandbox
  3. 00:03Container e7d6c8790de0 is up
  4. 00:03Seeded the repository at main (3e925b7)
  5. 00:03npm ciexit 0
  6. 00:03Record the baseline
  7. 00:03npm run testexit 0
  8. 00:03npm run typecheckexit 0
  9. 00:04npm run lintexit 0
  10. 00:04Baseline is green before any change
  11. 00:04Create plan
  12. 00:05Planner started with read-only tools
  13. 01:55submit_plan rejected: fields over 500 characters
  14. 02:22“Items need to be under 500 characters each. Let me shorten them.”
  15. 02:22Implementation plan recorded
  16. 02:22Implement change
  17. 02:22Implementer started inside the sandbox
  18. 04:35“errcode 2067 is SQLITE_CONSTRAINT_UNIQUE.”
  19. 04:35edit (sandbox)
  20. 04:35write (sandbox)
  21. 05:08“Now let me add the concurrent regression test.”
  22. 05:32edit (sandbox)
  23. 05:51“All 6 tests pass.”
  24. 06:06Validate change
  25. 06:06Diff recorded: 6 files, +147 −19
  26. 06:06npm run testexit 0
  27. 06:06npm run typecheckexit 0
  28. 06:06npm run lintexit 0
  29. 06:06Verified against the baseline
  30. 06:06Review patch
  31. 06:06Reviewer started with read-only tools
  32. 07:26Approved with 0 blocking findings
  33. 07:26Publish
  34. 07:30Committed rivet/job-9b3056ce-prevent-concurrent…
  35. 07:30Pushed the branch to GitHub
  36. 07:31Opened pull request #3
  37. 07:32Job completed

Pull request #3 opened

6 files changed, +147 −19, 24 model calls, $0.0141

A real job from August 20, 2026, replayed from its recorded event log at about 25 times speed.

7m 32s
from issue to pull request in the run above
1.4¢
of model usage for its 24 model calls
15 of 15
benchmark tasks passed hidden tests with review
1,400+
automated tests, from unit tests to real containers

How it works

Six steps, each one recorded. The screenshots come from the same job the console above replays.

  1. 01

    Start from an issue

    Pick a GitHub issue, or describe the task yourself. Rivet clones the repository into a fresh, disposable container and records how its tests, typecheck and lint behave before anything changes.

    The baseline matters later: it is how Rivet tells a failure it caused from one that was already there.

    The GitHub issue Rivet was given: prevent concurrent room double-booking
  2. 02

    Plan before touching code

    A planning agent reads the codebase and writes a structured plan: what is wrong, which files matter, how to reproduce it, how to fix it, and how to prove the fix.

    The planner can list, read and search files. It has no tool that can edit one, and Rivet checks that before the session starts.

    Rivet's implementation plan panel with problem interpretation and relevant components
  3. 03

    Write the change in a sandbox

    A coding agent makes the change inside the container, running commands and tests as it goes. Progress is saved after every step.

    Each step is a checksum-verified Git patch, so if a worker crashes, a replacement resumes from the last good step instead of starting over.

    The working tree diff Rivet produced, adding a unique index to booking slots
  4. 04

    Check the work

    Rivet reruns the project's own tests, typecheck and lint, then compares each result with the baseline from step one.

    New test failures are named individually, so a suite that was already red cannot hide a regression the change introduced.

    Rivet's validation panel showing the test suite, typecheck and lint verified against the baseline
  5. 05

    Get a second opinion

    A separate reviewer agent reads the issue, the plan, the diff and the test results. It approves, or sends specific feedback back for another round.

    The reviewer is read-only, and Rivet, not the model, decides how many revision rounds a job is allowed.

    Rivet's independent review panel showing an approval with no blocking findings
  6. 06

    Open the pull request

    Rivet commits the validated change, pushes a branch and opens an ordinary pull request for a person to review and merge.

    Every GitHub action records a receipt first, so a retry or a recovered job never pushes twice or opens a duplicate pull request.

    The pull request Rivet opened on GitHub for the double-booking fix

Demo video

Built to be trusted with a real repository

Having a model write code is the easy part. Most of Rivet is the system around it: what happens when something fails, what the AI is allowed to touch, and how you know the result is right.

It survives a crash
Kill the worker mid-job with kill -9. Another worker claims the job, rebuilds the sandbox from the last checkpoint, verifies its SHA-256, and carries on. A checkpoint that fails verification stops the job; Rivet never quietly starts over.
It contains the AI
The model's API key never enters the container running the cloned code. Each agent gets an exact set of tools, so the planner and the reviewer cannot write a byte, and Rivet verifies that set in code before every session.
It tells the truth about tests
Every check runs before and after the change. A test failure the change introduced fails the job, even in a suite that was already red; failures that were already there are reported as pre-existing.
It acts on GitHub exactly once
Pushes and pull requests write a receipt to Postgres before the job moves on. A retry, a reclaim or a second worker reads the receipt instead of repeating the action.
You can watch it think
Every phase, command, model call and GitHub request is an OpenTelemetry span, and the browser streams the job's append-only event log live. Budgets cap model calls, tokens, cost and wall-clock time per job.
It measures itself
An evaluation harness runs benchmark tasks as ordinary jobs, then grades each result in a second container against hidden tests the agent never saw.

How the pieces fit

Rivet architecture and sandbox trust boundaryThe browser reaches the Next.js web app. The web app and worker both call core directly. Postgres holds durable state, while Redis carries only job identifiers. Core uses queue, sandbox, coding agent, and telemetry ports. Pi and the model key stay on the trusted worker host, while repository code and tool execution stay in an untrusted container.Request pathBrowserpages + SSENext.js webRSC + API routesWorkerlease + pipelineShared coreone domain libraryDurable state and replaceable portsPostgresstate + event ledgerJobQueueSandboxCodingAgentTelemetryRedis / BullMQjob id + delivery onlyTRUSTED WORKER HOSTPi sessionsplanner · implementer · reviewertools execute in the sandboxmodel keyUNTRUSTED CONTAINERRepository sandboxsource · dependencies · testsno model key · no control-plane secretsOTLP
The web app and the worker share one domain library, with no network hop between them. Postgres is the source of truth; Redis only carries job ids and can be flushed without losing work. The agent sessions and the model key stay on the trusted worker host, while every file read, edit and command crosses into the disposable container through a sandbox-backed tool.

Built with

Interface
Next.js 16, React 19, server-sent events
Orchestration
Node.js worker, PostgreSQL with Drizzle, Redis with BullMQ
Execution
Docker sandboxes, the Pi agent harness, models via OpenRouter
Integration
A GitHub App with short-lived installation tokens
Operations
OpenTelemetry, Grafana, Tempo, Prometheus
Quality
TypeScript (strict), Vitest, 1,400+ tests, CI on every push

Does a second reviewer help?

Rivet can run a job with or without the independent review step. So it was measured rather than assumed.

Independent review

15/15tasks passed hidden tests

Model cost, all runs
$0.0675
Median runtime
143s

No review

14/15tasks passed hidden tests

Model cost, all runs
$0.0469
Median runtime
95s

5 benchmark tasks, each run 3 times with and without the reviewer, and graded against hidden tests. With review, every run passed. It cost $0.0206 more across all fifteen runs and took about 52 seconds longer per run.

Fifteen runs per side is a small sample: one extra pass is a signal, not proof that the reviewer caught a bug. The write-up says so, which is the point of measuring.

Run on August 17, 2026 with DeepSeek V4 Flash via OpenRouter. Read the experiment

Built by Hieu Le

I built Rivet to find out what it takes to trust an AI agent with a real repository. The model turned out to be the easy part. The work is everything around it: sandboxes, crash recovery, honest validation, and a record of every step that anyone can check.

Run it yourself

Rivet is a self-hosted, single-operator application. Clone it, start Postgres, Redis and Docker, add a model key, and point it at a repository.

$ git clone https://github.com/xuanhieu2611/Rivet.git
$ cd Rivet && pnpm install
$ pnpm db:migrate && pnpm dev