Skip to content
docs
Arxo ↗

Upgrades and replay

For LLMs5 sections

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. The example continues the lab’s versions exercise, after revision 0.2.0 of labparcels.registry has been published to /tmp/lab-work/registry (see Publishing a release). Status letters follow the legend on the topic index.

All commands and outputs in this section are verbatim from the versions exercise.

Preview. The currency check flags the new revision and exits 1. The lock stays untouched:

Terminal
law outdated --project fixtures/parcels-fees --registry lab=/tmp/lab-work/registry
Output
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:

Terminal
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
Output
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:

Terminal
law test /tmp/lab-work/fees-upd | tail -n 1
law outdated --project /tmp/lab-work/fees-upd --registry lab=/tmp/lab-work/registry
Output
total: 5 checked, 5 passed, 0 failed, 0 not run; code 0
Output
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

Section titled “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:

Output
law outdated [--project <dir>] [--registry <ID=LOCATION>]… [--json]

Observed excerpts from the top-level help, each line verbatim:

Output
$ law --help
law add <name>[@<version>] [--project <dir>] [--from <registryId>]
[--registry <ID=LOCATION>]… [--dry-run] [--json]
law install [--project <dir>] [--registry <ID=LOCATION>]… [--offline]
[--dry-run] [--recover] [--json]
law update <name>[@<version>] [--project <dir>] [--registry <ID=LOCATION>]…
[--dry-run] [--replay <dir>] [--json]
[…]
--offline exists only for install: add and update must read the registry
descriptors to build the closure, and cannot work offline.

Note the last lines: --offline is an install flag. Adding or updating by name requires registry reads, because selection needs the version listing. That is a narrower claim than “only install works offline”. The flag, registry reads, and needing the network are three different properties: a registry can live on a local path, and a release can cross an air gap inside a container (see offline transfer with containers). (S)

outdated has no dry-run flag. It never writes, so there is nothing to preview, and passing the flag is refused outright. Verbatim error-stream output, exit code 1:

Output
$ law outdated --dry-run
law: REFUSAL LPK-E0101: unknown parameter --dry-run
→ see `law --help`; registry form is ID=LOCATION, version is exact

The refusal changes nothing; drop the flag and run the command again.

install heals a working copy. --offline rebuilds from the local cache alone. --recover restores a damaged dependency directory without changing pins. Re-run the package scenarios afterwards: a heal that no scenario exercises proves nothing. (S)

A version pin plus a semantics line is not a replay. Repeating a saved result needs three more things:

  • the saved toolchain;
  • the input artifacts: the release bytes plus the saved evaluations;
  • the replay mechanism, which re-runs those evaluations and compares the result bytes.

A release too old to carry replay records cannot be replayed at all. Standalone releases carry those records in law.package-replay/0.2. eval replays one saved evaluation directory, as this real run shows (compiler warnings suppressed; both commands exit 0):

Output
$ law ask fixtures/parcels-case1 --query-json fixtures/parcels-case1/queries/fee-answered.json --out /tmp/eval-fee > /dev/null 2>&1; echo $?
0
$ law eval /tmp/eval-fee > /dev/null 2>&1; echo $?
0

What this result means: ask saved the evaluation of the fee question to /tmp/eval-fee, and eval re-ran that saved evaluation and finished with exit 0. Run such a replay before you reuse a saved result under a newer toolchain or a moved pin; if it does not finish with exit 0, read its output before relying on the saved result.

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.