exoDocs

How work ships

Environments

Preview, Staging, Release Candidate, and Production — one purpose, one artifact, and one approval boundary each.

Source: managed environment lifecycle. These are deployment stages, not product lifecycle labels. A project can be in private beta while running a production environment, and setting project.lifecycle to stable never authorizes a deployment.

Canonical names

StagePersistentDefault Git sourceRelease channel
PreviewNo, optionalRemote-canary or pull-request headInternal
StagingYesstagingInternal
Release CandidateYesreleaseCandidate
ProductionYesmainStable

Human-readable names follow the pattern {Project} · Staging. Provider names and generated URLs are separate operational metadata.

Preview (optional)

An ephemeral, server-backed environment for the exact pushed canary or pull-request head. It inherits staging configuration, uses isolated data when mutations are possible, and is removed when the pull request closes. It must never inherit production customer data or credentials.

Staging

The persistent integration environment, showing the combined state of upcoming work.

  • Source: staging. Agents never develop directly on it; they integrate validated commits from canary branches.
  • Deployment: every update automatically deploys after the projects.dev credential and spend gate passes. No owner approval sits between the branch update and the deployment.
  • Access: private by default, routed by the staging topology.
  • Optional services: integrations such as outbound email may stay disabled when staging-specific credentials are absent. Health and read-only routes must keep working.

Release Candidate

The production-like environment for the exact version proposed for the next release. It accepts fixes only after the candidate is cut, promotes the same verified build onward, and applies to any release worth freezing, including patches. Creating or replacing it needs explicit owner direction.

Production

The live environment. stable is its release channel label, not a name for the environment. It deploys only the approved Release Candidate artifact after explicit owner approval on the release → main pull request.

Promotion rules

  1. No stage implies approval for the next stage.
  2. The deployed commit, build checksum, configuration class, and approval evidence are recorded at every promotion.
  3. Secrets and persistent data are isolated by stage. Production values never flow backward.
  4. Rollback promotes a previously verified artifact or reverts through the normal approval path.
  5. Provider state is observed separately from project.yaml. Drift does not rewrite the contract.
  6. A provider capability is not configured until its environment, URL, access boundary, and lifecycle behavior are verified live.
  7. Every deployment needs fresh projects.dev evidence: credential inventory checked, billing visible, a spend limit configured, and no limit exceeded.
  8. Staging integration is not an approval gate. Domain, billing, destructive data, credential, and production migration actions keep their own approvals.
  9. Ordinary staging code delivery is automatic. Changing the provider binding, credentials, domain, billing configuration, or persistent data is a separately authorized mutation.
  10. Apps stage under staging.exo.now and Construct Pages under staging.construct.page. An App's production domain never owns its staging hostname.

Source: content/docs/shipping/environments.mdx

On this page