# Recovery and rollback

Recovery in Al-Amr means continuing from recorded evidence, never inventing or
replaying state. The CLI records non-secret checkpoints locally, Registry keeps
the authoritative publication state, and human gates record their decisions
with digests. This page collects the checkpoint formats, the resume contracts,
and the safe way back from every failure state.

## Local checkpoints the CLI records

The CLI writes the non-secret project link `.al-amr/project.json` with the
Registry origin, `projectId`, and last target and submission IDs. It records
those IDs locally before continuing, so an interrupted command can inspect and
reuse server state instead of starting over. These files contain no credentials
and are safe to commit.

`alamr status --json --non-interactive` is always the first read after an
interruption: it reconciles the local checkpoint with the authoritative
Registry state.

## Recover a bundle test

Environment and App frontends use one-pass Registry-held bundle tests. There is
no publisher-hosted frontend, well-known handshake, or test prepare/resume
handoff to reconstruct:

```sh
# Environment
alamr build --json
alamr test --bundle dist --json --visibility unlisted --channel preview

# App
alamr build --json
alamr test --yes --json

# Plugin
alamr test --json --visibility unlisted --channel preview
```

- Start recovery with `alamr status --json --non-interactive` and preserve the
  target, submission, snapshot digest, and artifact integrity it returns.
- If the build bytes did not change, rerun the same product-specific `test`
  command. The CLI reuses only the exact matching target and submission.
- If Environment bytes changed, bump `entry.version`, rebuild, and test the
  bundle again. If App bytes changed, rebuild and test again; the new build
  generation receives a fresh immutable revision.
- A Plugin keeps its version only when manifest and package bytes still match.
  Changed Plugin bytes require a SemVer bump. Its publisher-hosted HTTPS/WSS
  backend deployments remain separate reviewed targets.

## Device login handoff resume

When an agent or headless environment needs a human account session, the CLI
uses a structured device handoff instead of browser automation:

```sh
alamr login --device --json
# Human opens verificationUriComplete and confirms userCode.
alamr login --resume <handoffId> --registry <origin> --json
```

The first command returns one JSON document and never exposes the OAuth device
code. It pauses at `ALAMR_LOGIN_APPROVAL_REQUIRED`; after the human confirms,
the exact resume command completes the login. `ALAMR_LOGIN_APPROVAL_PENDING`
means the human has not approved yet: wait the returned `retryAfterSeconds`
interval and run the same resume command again. A missing or expired handoff is
not recoverable — start a new device flow; never reconstruct the pending file.

## Agent workflow human gates

Journey-driven automation stops at every declared human gate. A gate names its
actor (`human_owner`, `human_reviewer`, or `platform_admin`), the decision it
expects (`approve`, `reject`, or `attest`), the evidence it requires, and an
optional expiry between 60 and 86400 seconds. The workflow runner reports
`ALAMR_WORKFLOW_APPROVAL_REQUIRED` while a gate is pending and
`ALAMR_WORKFLOW_APPROVED` once the decision is recorded.

Resume is only valid after the recorded gate decision, with the exact actor,
target, snapshot, and evidence digest the gate declared. An agent must never
invent a decision, replay a mutation, or continue past a gate on the strength
of a screenshot or prose. Idempotent replay of an already completed workflow
returns `ALAMR_WORKFLOW_IDEMPOTENT_REPLAY` instead of repeating side effects.

## Recovery by publication state

| Current state or symptom             | Safe recovery                                                                                                                                                                                                                                                                        |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `draft`                              | Rebuild, then run the product-specific one-pass check: Environment `alamr test --bundle dist`, App `alamr test`, or Plugin `alamr test`. If the target is wrong, create a new immutable revision or version rather than editing frozen evidence                                      |
| `checks_running`                     | Read `alamr status --json` and wait for the current operation. Starting duplicate checks returns a conflict                                                                                                                                                                          |
| `checks_failed`                      | Read every structured check and correct the local bundle or deployment problem. Rebuild when bytes changed, then rerun the same product-specific `alamr test`; the CLI reuses only an exact matching target and reruns checks in place                                               |
| `ready_for_review`                   | Run `alamr publish` once. Repeated submission is unnecessary; use `status` to read the authoritative state                                                                                                                                                                           |
| `in_review`                          | Wait for an independent reviewer. The Project owner or submission author cannot approve it even with administrator authority; a project token cannot review                                                                                                                          |
| `rejected`                           | The transition is terminal. Registry can reset the same rejected submission to `draft` only when the exact frozen target and artifact snapshot still match. If code, manifest, Environment configuration, or deployment changed, create a new target; a Plugin requires a new SemVer |
| `withdrawn`                          | Create a new target and submission. Do not mutate the withdrawn evidence                                                                                                                                                                                                             |
| `approved`                           | Wait for the administrative `published` transition by a different platform administrator. If the artifact snapshot changed, publication fails closed                                                                                                                                 |
| `published`                          | Publish a new revision or release for changes. To return to older known-good content, use rollback to an eligible still-published target                                                                                                                                             |
| `yanked` or `suspended`              | These states cannot be reactivated by transition. Publish a new target or roll back to a different eligible published target                                                                                                                                                         |
| Snapshot or artifact digest conflict | Stop. Confirm the target IDs and artifact set. Never rewrite the digest; create a new immutable target when content changed                                                                                                                                                          |

## Yank and suspend effects

Both `yanked` and `suspended` are administrative, terminal transitions from
`published`. The transition requires a reason and is audit logged.

- For an Environment revision, Registry clears it as the active held bundle,
  revokes active Runtime sessions, and revokes linked Plugin Grants.
- For a Plugin release, Registry clears it as the active release and revokes
  Plugin Grants issued for that release.
- For a backend deployment revision, Registry marks the deployment suspended
  and revokes its Plugin Grants.

The original snapshot, review, and `publishedAt` evidence remain available.
For a yanked Plugin version, existing integrity locks remain reproducible, but
`alamr add` refuses a new installation of that version.

## Rollback without rewriting history

Rollback moves the Project's active pointer to a target that:

- belongs to the same Project;
- still has publication state `published`;
- is not covered by an active emergency block.

Rollback requires a reason and is audit logged. It never edits the target,
review, artifact, or earlier submission. Environment rollback also
selects the held bundle for the chosen revision. For an App, rollback, like the
final publish transition and global enable, reverifies the held bundle binding
before mutating state; historical App revisions without bundle evidence remain
readable but cannot be rollback destinations.

Plan and inspect first, then apply the exact saved plan:

```sh
alamr rollback <environment_revision|app_revision|plugin_release> <targetId> --reason <text> --plan
```

The CLI returns `ALAMR_ROLLBACK_PLAN_READY` with a plan digest; applying that
exact plan returns `ALAMR_ROLLBACK_PLAN_APPLIED`. Common failures are
`invalid_rollback` for a malformed request, `rollback_target_not_eligible` for
a target that is unpublished, blocked, or belongs to another Project, and
`project_recovery_admin_required` when the caller lacks administrator
authority. The documented Management API and Console call the same Registry
operation; never simulate rollback by editing IDs, digests, manifests, or
lockfiles.

For the state machine itself see
[Publication lifecycle](/docs/publish/publication-lifecycle); for error codes
met during recovery see [Troubleshooting](/docs/errors/troubleshooting); for
the review decisions that precede rejection or approval see
[Human review](/docs/publish/human-review).
