Upgrading
latticeVersion in lattice.json names the Lattice build this repo runs on.
lattice upgrade is how that pin changes, and it is the only command that
should change it: everything else — the version-drift check described below —
only reads it.
lattice upgrade
lattice upgrade 0.2.0
lattice upgrade latest
Given a version, lattice upgrade:
- Downloads that release’s binary into
.lattice/bin(skipped if it is already there — see Local binaries below). - Points the
.lattice/bin/latticesymlink at it. - Rewrites
latticeVersioninlattice.jsonto that version, editing the file as text so nothing else in it — key order, spacing, comments-free formatting — moves.
lattice upgrade latest resolves the newest stable release first; if the
project has not shipped a stable release yet, it falls back to the newest
pre-release and says so in its output, so nobody who typed latest is
surprised to find a pre-release pinned.
A version may be given with or without a leading v (0.2.0 or v0.2.0); it
is otherwise validated as semver and rejected with '<value>' is not a version
if it is not — the value ends up in a URL and a filename, so this doubles as
a guard against a path like ../../etc.
Once it finishes, lattice upgrade prints what changed and, if the version
just pinned is not the one you are currently running, a reminder of the exact
path to invoke it (./.lattice/bin/lattice, or its absolute path if you are
outside the repo). The command ends there:
◆ lattice upgrade
0.1.0 → 0.2.0
lattice.json now pins 0.2.0. Commit it so the whole repo moves together.
Run ./.lattice/bin/lattice to use it.
Commit the updated lattice.json. That single line is what moves the rest of
the team — the next section is how.
Local binaries under .lattice/bin
A repo keeps one binary per version it has ever pinned, named
lattice-<version>, plus a lattice symlink pointing at the current one.
Moving between versions already on disk — switching branches, undoing an
upgrade — is a symlink swap; only a version that is missing gets downloaded.
This is part of why rm -rf .lattice is a complete reset: it also removes
every locally installed Lattice build.
A downloaded archive is checked against the release’s published checksum
before it is installed. A mismatch fails the upgrade outright
(checksum mismatch) and leaves both the binary and lattice.json untouched.
If you re-run lattice upgrade for the version already pinned, and that
version is already installed, nothing is downloaded — Lattice still relinks
.lattice/bin/lattice to it and reports already on <version>, which covers
the one case where doing nothing would leave the repo pointed at the wrong
binary (for instance, after a branch switch left the symlink stale).
The version-drift check
Once a version is pinned, every other command checks it against the binary
that was invoked — a branch switch, a fresh clone, or a colleague’s lattice upgrade can easily leave you holding a different build than the repo now
pins. What happens next depends on where that binary came from.
A binary Lattice installed under .lattice/bin is switched automatically:
the invocation installs the pinned version if needed, relinks
.lattice/bin/lattice to it, and hands the command over to it in place, so it
runs as if you had invoked the pinned build directly. This is not advisory —
by the time anything prints, the switch is already happening:
◆ lattice 0.1.0 · this repo pins 0.2.0 · switching
If the pinned version cannot be installed (no network, no matching release), the command fails rather than silently running the wrong one, and says so:
this repo pins lattice 0.2.0, which is not installed and could not be fetched.
Run with --no-version-check to use lattice 0.1.0 anyway
Any other binary — a cargo install build, a debug build on PATH, a
package manager’s copy — is never replaced or switched. Lattice does not
overwrite a binary it did not put there. Instead, on an interactive terminal
running lattice run or lattice setup, it prints a one-line, advisory nag
and proceeds with the version you invoked:
◆ lattice 0.1.0 · this repo pins 0.2.0 · run `lattice upgrade 0.2.0`
This nag never appears in CI or raw output — see Output and logging for how that mode is chosen — and it never blocks the run. It is a suggestion, not a gate.
Silencing it
Both behaviors above — the automatic switch and the advisory nag — read the same three opt-outs, checked in this order:
| Opt-out | Scope |
|---|---|
--no-version-check |
This invocation only |
LATTICE_NO_VERSION_CHECK (any value) |
Every invocation in this shell/environment |
"settings": { "versionCheck": false } in lattice.json |
Every invocation in this repo, for everyone |
With any of these set, a command runs as invoked, drift and all — no switch,
no nag. versionCheck defaults to true.
latticeVersion: what it does and does not enforce
{
"$schema": ".lattice/schema.json",
"latticeVersion": "0.2.0",
"workspaces": []
}
latticeVersion is read directly out of the JSON, before lattice.json is
otherwise parsed or validated against the schema. That is deliberate: a config
written for a newer schema still has to be readable enough to say which
version can read it, even if this binary would otherwise choke on it.
What declaring it does:
- Drives the switch/nag behavior above.
- Is what
lattice upgraderewrites.
What it does not do:
- It does not pin or validate anything about the schema
lattice.jsonis written against — there is no per-version schema compatibility check beyond whatever this binary’s own parser accepts. - It does not block a command from running under a different version when
the check is silenced, and it is never required — a
lattice.jsonwith nolatticeVersionat all is valid; nothing drifts because there is nothing to drift from.
What an upgrade means for the cache
The running Lattice version is one of the inputs hashed into every task’s cache key, alongside its command, its input files, and its resolved toolchains. Changing that version changes every task’s key, so the first run after an upgrade is a cache miss across the board — every task re-executes and re-populates the cache under the new key. Nothing is corrupted or lost; old entries simply stop being looked up, and are evicted the same as any other unused entry. See Caching for the rest of what the key is built from and how eviction works.