## Where it lives

```bash
bin/rails routes | grep configurations
```

The route is declared in `config/routes.rb`, constrained to `ios` or `android`, and handled by a
controller that returns the rules as JSON. Because it is served rather than compiled in, it is
changeable at the same speed as everything else on your server.

## What the rules do

Each rule matches a URL pattern and sets a presentation. The common ones:

- **Modal** for anything that is a task rather than a place: a new record form, a confirmation.
- **Replace** for a screen that should not add to the back stack, such as a post-submit result.
- **Native** for the marker paths the shell must intercept rather than load, which is how the in-app
  purchase sheet appears.

## Per platform, deliberately

The route takes a platform because iOS and Android have different navigation conventions, and
pretending otherwise produces an app that feels wrong on one of them. A sheet that is right on iOS
may want to be a full screen on Android.

## Test the back behavior

The failure this causes is not a crash, it is a back button that goes somewhere unexpected. After
changing a rule, walk the flow forwards and backwards on a device. A modal that pushes instead of
presenting leaves users on a screen with no way out, and that is a rejection as well as a bug.

## Do not put logic here

Path configuration decides presentation, not permissions. A screen that should be hidden from
unentitled accounts is gated in the controller with the concern in
`app/controllers/concerns/require_entitlement.rb`, not by omitting a navigation rule. The URL is
still reachable, and a rule is not a gate.

## Changing it is instant, within reason

The shells fetch the configuration at launch, so a change lands on the next cold start rather than
mid-session. That is fast enough to fix a navigation bug the same day, which is the whole point of
serving it.
