# Staging topology

https://exo.now/docs/shipping/staging

> Exo owns staging for Apps; Construct owns staging for Pages. Review routes follow ownership, not production hostnames.



Source: [Exo staging topology](../../../docs/staging-topology.md).

## Canonical routes [#canonical-routes]

| Resource       | Canonical staging route                 | Example                              |
| -------------- | --------------------------------------- | ------------------------------------ |
| Exo platform   | `https://staging.exo.now`               | The Exo control plane                |
| App            | `https://staging.exo.now/{app}`         | `https://staging.exo.now/rampart`    |
| Construct Page | `https://staging.construct.page/{page}` | `https://staging.construct.page/dan` |

Construct is an App, so it stages at `staging.exo.now/construct`. It is also the Page platform,
so the Pages it manages stage on `staging.construct.page`.

## Routing and authorization [#routing-and-authorization]

The canonical route is a gateway address. A provider-generated hostname is an operational
coordinate and a source of deployment evidence, never the review URL.

1. The shared origin authenticates the session.
2. The gateway resolves the first path segment to a declared App or Construct Page.
3. The server validates an active, environment-specific Exo grant for that resource.
4. The gateway forwards only to the declared provider target and keeps the canonical browser URL.

Apps share one non-production identity plane without every signed-in user getting access to every
App. Health checks and signed webhooks keep narrow, documented exceptions.

<Callout title="Identity" type="info">
  Exo Key (Exo ID) authenticates the shared staging origin; Clerk is removed
  ([ADR 0012](../../../docs/adr/0012-clerk-removed-convex-auth-everywhere.md)). The gateway checks
  an Exo ID session and an exact staging grant before it opens an app path
  ([staging access](../../../docs/staging-access.md)).
</Callout>

## Adoption inventory [#adoption-inventory]

The last verified observations recorded in the topology doc:

| Resource                | Route                           | Status                                                                      |
| ----------------------- | ------------------------------- | --------------------------------------------------------------------------- |
| Exo                     | `staging.exo.now`               | Verified live                                                               |
| Construct               | `staging.exo.now/construct`     | Verified live (Construct commit `875ac2e`)                                  |
| Rampart                 | `staging.exo.now/rampart`       | Verified live; removal of `staging.rampart.fit` is a separate domain action |
| Observatory             | `staging.exo.now/observatory`   | Verified live                                                               |
| Cosmograph              | `staging.exo.now/cosmograph`    | Verified live                                                               |
| Vector                  | `staging.exo.now/vector`        | Provisioning required                                                       |
| Universe                | `staging.exo.now/universe`      | Provisioning required                                                       |
| Dropship                | `staging.exo.now/dropship`      | Verified live                                                               |
| Construct-managed sites | `staging.construct.page/{page}` | Per-Page migration                                                          |

A route is never marked live from configuration alone. It needs provider health, exact-commit
evidence, and a browser pass.

## Per-resource migration checklist [#per-resource-migration-checklist]

1. Classify the resource as `platform`, `app`, or `construct-page`, and reserve its slug.
2. Record the current provider service, source branch, provider URL, and verified commit.
3. Configure gateway routing for the target path without changing Production.
4. Configure the non-production authorized origin and the resource-specific Exo grant.
5. Verify unauthenticated denial, authorized success, cross-resource denial, return paths, health,
   noindex headers, and the exact deployed commit.
6. Review the canonical URL in a browser.
7. Remove the old app-domain staging route, or make it redirect-only.
8. Attach evidence to the Exo work and release records.
