# App availability

Publishing an App revision makes it the App's active published revision; it
does not make the App launchable. Runtime availability is a separate platform
decision: a platform administrator enables or disables an exact published
revision. App publication alone never creates global availability.

## The availability record

Registry keeps one availability record per exact App revision, read through
`GET /v1/admin/apps/availability`:

| Field             | Meaning                                                             |
| ----------------- | ------------------------------------------------------------------- |
| `appId`           | The stable App ID                                                   |
| `revisionId`      | The exact immutable revision this record governs                    |
| `revision`        | The revision number                                                 |
| `publisherHandle` | The Publisher handle that owns the App                              |
| `slug`            | The App slug under that Publisher                                   |
| `enabled`         | Whether this exact revision is currently enabled for Runtime launch |
| `blocked`         | Whether the revision is under an active emergency block             |
| `publishedAt`     | When the revision was published                                     |
| `updatedAt`       | When the availability decision last changed, or `null`              |

Availability is per exact revision: enabling a new revision and disabling an
old one are independent audited decisions, not an automatic pointer move.

## Authority boundary

Both the read and the mutation are platform-administration operations:

1. The caller must be a platform administrator; project tokens and Project
   membership are rejected with `admin_required`.
2. Every mutation carries a reason from 3 to 1000 characters.
3. The availability update and its `app.platform_availability.set` audit event
   commit in one transaction, with the administrator, App, revision, enabled
   state, scope, and reason recorded.

The mutation endpoint is `PUT /v1/admin/apps/availability` with `appId`,
`revisionId`, `enabled`, and `reason`. A malformed body returns
`invalid_app_availability`; an unknown revision returns
`app_revision_not_found`.

## Enable an exact revision

1. Confirm the revision is `published` and read its current availability row.
2. Verify the operator intent: the exact `appId` and `revisionId`, and the
   immutable build digest.
3. Submit the enable mutation with the reason.
4. Confirm the updated record shows `enabled: true` for the exact revision.

Before enabling, Registry re-verifies the build binding for that exact
revision: the revision names exactly one inventory, and that inventory still
recomputes to the digest it was bound under. If it does not, the mutation fails
closed with `app_build_artifact_invalid` or `app_build_artifact_required`
rather than enabling bytes nobody reviewed. Historical revisions that predate
build evidence remain readable but cannot be newly submitted, published,
enabled, or selected as rollback destinations.

## Disable an exact revision

Disabling uses the same endpoint with `enabled: false` and its own reason. The
revision's publication state is untouched: disabling removes Runtime launch
eligibility, it does not yank or suspend the publication. A disabled revision
can be enabled again through the same audited mutation while it remains
published and unblocked.

## Interaction with blocks and rollback

- A revision under an active emergency block reports `blocked: true`; the
  launch path independently rejects blocked revisions, so availability is never
  the only enforcement layer.
- Rollback of the active published pointer and the availability enable both
  repeat live build readiness before mutating state; neither trusts stale
  evidence. See [Recovery and rollback](/docs/publish/recovery).
- Availability never changes catalog publication: the published revision stays
  visible in the catalog while disabled.

## Operator verification

Enabling is complete only when a real consumer launch proves the exact revision
runs in an independent Runtime. The App authoring journey asserts this
completion; a missing consumer launch proof fails the journey with
`ALAMR_APP_LAUNCH_MISSING`. Do not treat a successful mutation response as
launch evidence.

For the review and publication stages that precede availability see
[Publication lifecycle](/docs/publish/publication-lifecycle); for the stable
error codes see [Troubleshooting](/docs/errors/troubleshooting).
