Markdown for LLMs
Rollback
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# Rollback ## Goal Return a deployment to the last accepted state — runtime binary plus pinned world — quickly, in a defined order, with explicit success criteria and known limits. ## Scope Component `law` CLI + serve deployment, tool `0.1.1`. Scenario: the new state (after an upgrade switch per [Upgrades and compatibility](/operate/upgrades-compatibility/)) is rejected during the observation window; the prior bundle, lock, and binary were kept on the host. All identifiers below are synthetic created-examples. ## Prerequisites - The prior state intact on the host: prior `.arxo` bundle + hashes, prior `law.lock`, prior `law` binary path (or reinstallable pinned archive + `.sha256`). - The rejected state's identity recorded: new bundle name, new pin (`GET /v1/world` output), new `law version --json`. - The decision journal preserved. One journal directory is shared across generations: every record carries its world's pin, so entries from the prior window and the rejected window normally coexist in the same directory. Windows are distinguished by recorded pin and decision id, not by separate directories. ## Steps 1. Declare the rollback: record which state is rejected and why; freeze further switches (operator-policy-example: page the change owner — created-example process). 2. Stop intake on the rejected world: disable the ingress route, then stop `law serve` and confirm the PID is gone (no graceful drain exists — in-flight calls die; only completed decisions have records). Fencing the port alone does not stop writers. 3. Switch order — data-plane first, then control-plane (operator-policy-example order): (a) restore the prior world directory from the labeled backup set (`--world` accepts a directory or a `profile.json`, never a `.arxo` bundle directly), then repoint the `--world` symlink to it; (b) if the runtime binary also moved, restore the prior binary path — runtime and world roll back together, never the world alone under a rejected binary. 4. Verify integrity of the selected artifacts and configuration BEFORE starting anything (real): `law inspect <prior-bundle> --verify --trust <key>`. Do not rely on the runtime to refuse damaged artifacts implicitly — a rollback procedure must not start a state it has not checked. 5. Start the chosen runtime + world pair with external traffic still fenced off. Step 2 stopped the process, so no running watcher can warm the prior world for you — this recipe always restarts; a hot rollback that relies on `--watch-world` without stopping would be a different procedure. 6. Check readiness and identity on the fenced instance, in this order: `GET /readyz` is `200`, then `GET /v1/world` shows the prior pin. Re-run acceptance on the restored state (real): `law test` over the prior project, `law eval` over a saved calculation, and `law replay-record --world <prior> --journal <dir> --decision <id>` for the prior window's decision ids. Each record is pin-checked against the loaded world; a record from another generation reports `PIN_MISMATCH` instead of replaying silently. Finish with one synthetic control query through `POST /v1/ask` (real endpoint) and confirm the expected document. 7. Open ingress only after step 6 is fully green. 8. Fate of the rejected window's cases and records: keep the journal whole — do not delete rejected-window records and do not rewrite history (the journal has no rewrite command — implementation limit). Decisions served during the rejected window stay recorded with the rejected pin; re-ask any affected cases against the restored world explicitly (new journal entries, new decisions). Select records by recorded pin and decision id; there is no supported "split this journal into two directories" procedure. 9. Mutable-data compatibility: if host-side systems consumed rejected decisions (tickets, payments, notifications), reconcile them case-by-case from the preserved rejected-window records; the tool cannot retract served decisions (implementation limit, not a missing flag). ## Expected result - `GET /v1/world` reports the prior pin; `/readyz` is `200`. - `law test`, `law eval`, and `law replay-record` exit `0` on the restored state. - The journal preserved whole; prior-window and rejected-window records remain distinguishable by recorded pin. ## Result check - Pin check: served pin equals the recorded prior pin, not merely "an old pin". - Replay check: prior-window journal replays cleanly (`resultHash`/`outcomeHash` match per entry). - Diff check: `law case diff` between a pre-upgrade saved evaluation and a post-rollback fresh ask of the same case is empty. - Intake check: one synthetic ask through `POST /v1/ask` (real endpoint) returns the expected document before real traffic resumes. ## Failures and diagnostics - `/readyz` not `200` after the step 5 restart: the prior world did not warm — check the symlink target, bundle readability, and server stderr; serve was possibly started against a pruned path. - `law replay-record` mismatch on the prior journal: the "prior" world is not byte-identical to the accepted one (re-pack drift or lock edit); restore from the labeled backup set ([Backup and restore](/operate/backup-restore/)). - Prior binary missing: reinstall from the pinned archive + `.sha256` (per [Install and trust artifacts](/operate/install-trust-artifacts/)) rather than downgrading through a package manager's "latest". - Records from several pins in one journal: normal after any `--watch-world` switch, not a fencing failure. Select by recorded pin and replay each record against the world that matches its pin. ## Support boundaries - Supported: world + runtime rollback via kept bundles, locks, and binaries; per-entry replay verification. - Implementation limits: no journal merge/rewrite/retract commands; no automatic rollback trigger — the switch is always an operator act. - Rollback limits: rollback restores the answering state, not the consequences of rejected answers; downstream effects need case-by-case reconciliation. "Safe rollback" in this article means only "the defined order was followed and all checks are green". ## Next step File the rollback report (rejected pin, cause, affected decisions, reconciliation list) and re-plan the upgrade as a new change; do not re-attempt the same switch without a new review.