# Upgrades and replay Upgrading a dependency means moving a pin forward deliberately: preview what is newer, stage the move, and re-run the affected scenarios to prove the move is safe. This page covers the preview command, the upgrade command with its replay support, and offline repair. Environment: the public `law-v0.1.1` release, run from the root of the [lab bundle](/corpus/lab/#before-you-start). The example continues the lab's [versions exercise](/corpus/lab/solutions/#versions-exercise), after revision `0.2.0` of `labparcels.registry` has been published to `/tmp/lab-work/registry` (see [**Publishing a release**](/corpus/releases/publishing/)). Status letters follow the [legend on the topic index](/corpus/#how-this-topic-marks-confidence). ## Example: move one pin forward All commands and outputs in this section are verbatim from the [versions exercise](/corpus/lab/solutions/#versions-exercise). **Preview.** The currency check flags the new revision and exits 1. The lock stays untouched: ```shell law outdated --project fixtures/parcels-fees --registry lab=/tmp/lab-work/registry ``` ```text lab ← /tmp/lab-work/registry (--registry) labparcels.iface@0.1.0 [lab]: up to date labparcels.registry@0.1.0 [lab]: published 0.2.0 ``` Each pin is compared only against newer releases of the same package. Here one pin is behind, so one package is a candidate for an upgrade. **Stage.** Copy the consumer (the copy is silent), then run the upgrade with the preview flag: ```shell cp -r fixtures/parcels-fees /tmp/lab-work/fees-upd law update 'labparcels.registry@0.2.0' --project /tmp/lab-work/fees-upd --registry lab=/tmp/lab-work/registry --dry-run ``` ```text lab ← /tmp/lab-work/registry (--registry) --dry-run: staged and verified, no file changed ~ labparcels.registry 0.1.0 -> 0.2.0 changed: .law/transport.json changed: deps/labparcels.registry.lawir.json changed: law.lock changed: law.toml changed: package.law ``` The staged copy verified, and the `changed:` lines list the files a real run would write. No file changed yet. **Apply and confirm.** Run the same command without the preview flag (its output repeats the list above without the `--dry-run` line), then run the consumer scenarios and the currency check again: ```shell law test /tmp/lab-work/fees-upd | tail -n 1 law outdated --project /tmp/lab-work/fees-upd --registry lab=/tmp/lab-work/registry ``` ```text total: 5 checked, 5 passed, 0 failed, 0 not run; code 0 ``` ```text lab ← /tmp/lab-work/registry (--registry) labparcels.iface@0.1.0 [lab]: up to date labparcels.registry@0.2.0 [lab]: up to date ``` What this result means: the consumer now pins `0.2.0`, all five of its scenarios pass on the new pin, and no pin is behind. That justifies committing the new `law.toml`, `law.lock`, `deps/`, and import line together. A failing scenario at this point would mean the revision changed behavior the consumer relies on; keep the old pin until the cause is understood. ## Preview with outdated, upgrade with update `outdated` compares each pin against the newer stable releases of that same package and checks whether the pinned bytes still match. It never touches the lockfile. The comparison is per package, never against sibling versions: in the lab, `labparcels.fees` sits at `0.2.0` while its siblings sit at `0.1.0`, and the report above still flags only the registry pin. **Available in the public release** (S). `update` moves a pin and can replay saved evaluations as part of the move, so regressions surface before the new lock is accepted. The dry-run flag stages and verifies the move without changing any file. (S) The command reference records this usage for the preview command: ```text law outdated [--project