Your agent says it's done. Are you ready to own it in production?

Owning it means understanding it. Reboot is the framework that lets you actually review what your agent builds: you work at the level of your domain model, and your app's behaviors are plain sentences that run as tests.

  1. curl -fsSL https://reboot.dev/install.sh | bash

    Works with Claude Code and Codex.

  2. “Build me a bank where customers open accounts, deposit, withdraw, transfer between them, and earn interest.”

  3. Reboot's developer dashboard updates as the agent writes. Types and methods appear first, then the calls between them.

  4. Overdrafts are refused becomes a test that runs against the same methods your app runs in production.

Open source under Apache 2.0.

Why agent-written code fails

Your agents build the happy path. Production runs every path.

Your agent has written more code than you can review. It started from a clean spec, but got fragmented across databases, ORMs, queues, caches, lambdas, workflow engines, and services. Along the way, the agent invented its own concurrency, transactions, retries, and recovery, the kind of code whose bugs only show up in production. Checking its work now means reverse-engineering the domain model from source code.

The agent wrote it, but you are responsible for it.

Without Reboot

one account · 6 places
  1. REST handler POST /accounts/{id}/deposit
  2. ORM model class Account(Base)
  3. Postgres table accounts
  4. Redis cache balance:{id}
  5. Kafka topic account.deposited
  6. Temporal workflow TransferWorkflow
Where is the rule that a balance never goes below zero? Somewhere in there.

With Reboot

one account · 1 place
An Account is just an Account: its state, and the methods that may touch it. Nothing else to piece together.

Spec-driven development without drift

With Reboot, the domain model is the application.

The domain stays visible. Named types such as Account, Customer, and Bank remain the domain you review and the application Reboot runs.

The dashboard shows those types, their behaviors, and their call graph, as implemented in the code. It is not a separate specification that can drift; it is the application running in production.

  • Visible

    Read from your code: every type, every method, and who calls whom. It can't drift, because it isn't a copy.

    bank.v1 Account open factory balance deposit withdraw interest schedules STATE TYPE Account 1 property · 5 methods PROPERTIES balance number METHODS open writer balance reader deposit writer withdraw writer interest writer
  • Reviewable

    Review the application at the level you designed it. You see that transfer calls deposit and withdraw without opening a file.

    Bank transfer create sign_up open_customer_account all_customer_ids account_balances Account deposit withdraw open balance interest
  • Enforceable

    Behaviors are sentences that run as tests. The dashboard shows which methods each one covers, and which methods nothing covers.

    FEATURE Customers can deposit into an account RULES A deposit is a positive amount USES Account.balance Account.deposit Account.open FEATURE Customers can withdraw from an account RULES Overdrafts are refused USES Account.balance Account.deposit Account.open Account.withdraw NOT USED BY ANY FEATURE User.create User.set_claims

Behaviors in plain sentences

Write the rule in English. Reboot runs it as a test.

You describe what your app should do in plain sentences, built from your domain model's own nouns and verbs. Each one runs as a test against the same methods your app runs in production, so the words and the code cannot drift apart. And because Reboot handles durability, retries, and failures, passing the test means the feature works: there is no second layer of plumbing to verify.

You get to focus on the parts that matter: rules and behaviors — the decisions that affect your customers and your business.

Test run pytest
tests/deposits.feature Failing
Rule: A deposit is a positive amount A deposit only ever adds to the balance: one of zero or less aborts, saying the amount that was asked for, and leaves the balance as it was. Scenario Outline: Depositing zero or a negative amount aborts with the amount Given "alice" is an authenticated user And "alice" creates an `Account` via `open` And the resulting state id is saved as "account id" When "alice" does a `deposit` with `amount=10.0` on `Account` of "<account id>" And "alice" attempts a `deposit` with `amount=<deposit>` on `Account` of "<account id>" Then as "alice", `balance` on the `Account` for "<account id>" has `amount=10.0` Runner output: Expected `amount` to be 10.0, but it is -40.0. And the attempt aborts with `NonPositiveAmountError` with `amount=<deposit>` Examples: | deposit | | -50.0 | | 0.0 |

The rule said a deposit is positive. The code let −50 through.

backend/src/account_servicer.py Account.deposit · writer
async def deposit(    self,    context: WriterContext,    request: Account.DepositRequest,) -> None:    if request.amount <= 0:        raise Account.DepositAborted(            NonPositiveAmountError(amount=request.amount)        )    self.state.balance += request.amount

The deposit method checks the amount before touching state and aborts with a declared error.

tests/deposits.feature Passing
Rule: A deposit is a positive amount A deposit only ever adds to the balance: one of zero or less aborts, saying the amount that was asked for, and leaves the balance as it was. Scenario Outline: Depositing zero or a negative amount aborts with the amount Given "alice" is an authenticated user And "alice" creates an `Account` via `open` And the resulting state id is saved as "account id" When "alice" does a `deposit` with `amount=10.0` on `Account` of "<account id>" And "alice" attempts a `deposit` with `amount=<deposit>` on `Account` of "<account id>" Then as "alice", `balance` on the `Account` for "<account id>" has `amount=10.0` And the attempt aborts with `NonPositiveAmountError` with `amount=<deposit>` Examples: | deposit | | -50.0 | | 0.0 |

Now the rule is enforced, and every run proves it.

Built in, not generated

Reboot handles the rest of the backend.

Python backends today. TypeScript backends are in alpha.

One source of truth

The model is the code, all the way down.

What you see in the dashboard is what exists in your API; there is nothing to keep in sync. And the code is there if you need to take a closer look.

01 The Account card, in the model view

Models bank.v1 Live
bank.v1
Account bank/v1/account.py
state balance number
  • open factory writer
  • balance reader
  • deposit writer
  • withdraw writer
  • interest writer

02 The Account state type, declared in Pydantic

Account bank/v1/account.py
class AccountState(Model):
    balance: float = Field(
        tag=1,
        description="What the account holds, in dollars, and never below zero.",
    )

api = API(
    Account=Type(
        state=AccountState,
        methods=Methods(
            deposit=Writer(
                request=DepositRequest,
                response=None,
                errors=[NonPositiveAmountError],
                mcp=Tool(),
            ),
            withdraw=withdraw,
            balance=balance,
        ),
        description="One customer's money, in one account.",
    ),
)

03 The deposit method, as implemented

Account.deposit Writer
async def deposit(
    self,
    context: WriterContext,
    request: Account.DepositRequest,
) -> None:
    if request.amount <= 0:
        raise Account.DepositAborted(
            NonPositiveAmountError(amount=request.amount)
        )
    self.state.balance += request.amount

One backend to serve every user — human or machine.

Build anything with Reboot: a web app, a mobile app, MCP tools an agent can call, and MCP apps that can render UIs inside ChatGPT and Claude.

Run agents within your app too: no need for a separate framework!

bank.v1 1 model · 6 ways to access
Humans Machines Web Mobile MCP apps MCP tools Agents Services Humans Machines Web Mobile MCP apps MCP tools Agents Services

The class of bugs that is even possible is just dramatically smaller.

Alex Clemmer CEO, moment.dev Previously Pulumi, Microsoft

Get started

Reboot is open source under Apache 2.0. Run it on your own servers or on Reboot Cloud.

curl -fsSL https://reboot.dev/install.sh | bash