## Prove it in two commands

```bash
bin/setup
bin/dev
```

No `.env` to fill in first. The database is SQLite, so there is no Postgres to install and no Redis
to run. Sign in with a magic code, which opens in a browser tab rather than sending. Buy a
subscription, which completes against the local fake. Open a gated feature, which unlocks.

## How the seam works

`app/adapters/billing.rb` is the reference implementation, and the others copy its shape:

```ruby
Billing.for(account)
```

One method, two possible implementations, and nothing else in the app knows which it received. Both
live under `app/adapters/billing`, and the fake is short enough to read in a minute, which is the
point: it documents what the real one is expected to do.

`app/adapters/bot_check.rb` and `app/adapters/error_reporter.rb` follow the same pattern.

## What the fakes do not cover

They are deterministic, not simulations. Card declines, real webhook timing, actual email
deliverability and real bot traffic all need the real service. So the fakes are right for
development and for the test suite, and wrong as a substitute for one round of testing against test
mode before you launch.

## The one key production needs

`RAILS_MASTER_KEY`, and nothing else. Every other variable in
`docs/BRING_YOUR_OWN_KEYS.md` is optional, and an app missing one runs on that integration's fake
rather than raising. That is what makes it reasonable to deploy before you have decided on a payment
provider.

## Adding your own integration

Use the `add-integration` skill. It builds the same adapter and fake pair for a new service, which
keeps the "works with no accounts" property true as the app grows. Calling a third-party API directly
from a controller is the thing that breaks it.
