Changelog
This page curates the user-facing history from the repo’s own CHANGELOG.md,
newest first. That file is the source of record; this page drops the entries
that only matter to someone working inside the repo and links out to the
relevant docs where they exist.
Lattice is currently at 1.0.0-beta-2 — a pre-release build; there is no
1.0.0 yet. Versions follow semver: a major bump means a breaking change to
the lattice.json schema or the CLI surface. A version bump is also a full
cache miss, because the running version is one of the inputs hashed into every
task’s cache key, so the first run after an upgrade re-runs everything. See
Upgrading and Caching.
Installing, upgrading, and running the version a repo pins — 2026-07-28
Lattice can now be installed without a Rust toolchain, and a repo’s
latticeVersion is enforced rather than merely announced. See
Installation and
Upgrading.
curl | sh installs a target-matched binary into the repo
- The installer detects the OS, architecture and libc, resolves a version,
downloads the matching release archive, verifies its SHA256 against the
release’s checksums file, and installs
./.lattice/bin/lattice-<version>with./.lattice/bin/latticesymlinked to it. Nothing is written outside.lattice, sorm -rf .latticeis the uninstall - Version resolution, in order:
$LATTICE_VERSION, thenlatticeVersionfrom./lattice.json, then the newest release when the directory has no config at all. Alattice.jsonthat exists but pins nothing is an error - It fails loudly, before installing anything, on an unsupported platform, a missing pin, a missing release asset, a missing checksums entry, or a digest that does not match
.lattice/bin/is now one of the.gitignorelineslattice initmaintains
Every invocation runs the version the repo pins
- A binary under
.lattice/binwhose version differs fromlatticeVersionnow prints one line naming both versions, installs the pinned version if it is not already on disk, repoints the symlink, and hands the invocation over to it with the arguments untouched. Switching between two branches that pin versions you already have is a symlink swap and touches no network - A binary Lattice did not install —
cargo install, a distro package, a local dev build — is never replaced. It gets an advisory one-line nag instead, with a runnablelattice upgrade <version> --no-version-check,LATTICE_NO_VERSION_CHECKandsettings.versionCheck: falseeach skip the whole thing.upgrade,versionandcompletionsare never handed off: they answer for the binary that was invoked, and a completion script has to be the only thing on stdout- A pinned version that cannot be installed is a hard failure naming the version and the way past it, rather than silently running a build the repo did not ask for
lattice upgrade <version|latest>
- Installs the version, points
.lattice/bin/latticeat it, and rewriteslatticeVersion.latestresolves the newest release; a bare version pins it exactly, with or without a leadingv - The config is edited as text, so key order, indentation and the rest of the file survive a bump
- Re-running for a version already pinned and installed reports that and repoints the symlink — the one case where doing nothing would leave the repo on the wrong binary
Releases are published for six targets
- macOS x86_64/aarch64, Linux x86_64 (gnu and musl), Linux aarch64, and
Windows x86_64, as
lattice-<version>-<target>.tar.gzarchives carrying the binary, the license and completion scripts, alongside onelattice-<version>-checksums.txtand the installer itself
Four documented promises the code did not keep — 2026-07-28
Groundwork for the first tagged release: statements in the README, the docs, or a manifest that the code contradicted.
- The minimum Rust version is
1.86, not the1.75every doc previously claimed — the real floor, once the lockfile is resolved against each dependency’s own requirement, comes fromclap,sha2,indexmap, and the ICU crates reached throughjsonschema lattice version --jsonnow reports a real target triple (aarch64-apple-darwin) in itstargetfield instead of a bare architecture (aarch64); the bare architecture moved to its ownarchfield rather than being dropped. See CLI reference- Windows is not supported:
lattice-workspace’s toolchain probe hardcodes a Unix shell and a UnixPATHseparator, so engine version checks and toolchain provisioning cannot work there. The docs now say macOS and Linux, and point Windows users at WSL2. See Installation
Long durations print as a clock — 2026-07-28
- Task and run times over a minute now read
4:07and1:12:30instead of247.00sand4350.00s. Under a minute is unchanged (1.23s). Applies everywhere Lattice prints a duration: per-task completion lines and the run summary, in both the interactive and CI reporters. See Output and logging
Nested repos: docs, worked example, and tests — 2026-07-28
- A subtree that already has its own task runner can be declared as a manual
workspace whose
scriptsshell out to that runner — ordering,dependsOn, caching as one opaque unit, and validation all fall out of the existing workspace mechanism, with no separate feature needed - Two limitations: a manual workspace must declare any task invoked directly, and a downstream workspace must not copy an upstream artifact at build time, because a cache key covers only the inputs its own workspace declares
examples/nested-repoships as a runnable worked example: a JS monorepo (npm workspaces, two packages, an inner dependency edge) as one Lattice node, plus a downstream service. See Nested repos
Docs site search — 2026-07-28
- Full-text search over the documentation, opened with
⌘K/Ctrl-Kor/, navigable with the arrow keys, listing heading-level matches beneath each page so a long page points at the section that matched
Persistent tasks stream their output by default — 2026-07-27
- A
lattice runthat pulls in a persistent task — a dev server, a watcher, or anything in its dependency closure — now defaults to raw line-by-line output instead of the live TUI, so the process’s streaming output stays visible; this previously required-l(--loquacious) - Non-persistent runs on a terminal still get the interactive TUI
- A persistent task’s output always streams live even in raw mode, while other per-task output stays collapsed and is surfaced on failure
- Auto-detection no longer fabricates a command for a persistent task: a
direct-invoke driver (
cargo,go, …) used to invent a command for any task name, solattice run devpicked up every Rust and Go workspace ascargo devorgo deveven though no such task exists - A persistent task now runs only where the workspace declares it, through an
explicit
scriptsentry or a manifest script for the JS and Deno drivers; non-persistent tasks (build,test, …) still infer as before. See Persistent tasks and Output and logging
Stacked commands and a self-healing editor schema — 2026-07-27
lattice runaccepts multiple tasks in one invocation (lattice run lint test build); the roots merge into a single dependency graph, so a dependency shared by several roots runs once and independent roots parallelize where the graph allows- All existing flags (
--filter,--concurrency,--continue,--dry-run,--no-cache) apply to the combined run, and an unknown task in the list fails fast and names the offender --sequentially/-sruns each task’s graph to completion in the order given before starting the next; fail-fast stops at the first failed phase, and--continueruns the remaining phases and still exits non-zerorun,setup, andprunewrite.lattice/schema.jsonwhen it is missing, as happens with a cleared cache directory or a clone where it was never committed, so an editor’s JSON language server can resolve the config’s$schema. An existing copy is left untouched to avoid churn. See Task graph and CLI reference
The documented install command installed the wrong software — 2026-07-27
- The docs site told readers to run
cargo install lattice, butlatticeon crates.io is an unrelated markdown linter, so anyone following the getting-started page or the landing-page copy button got someone else’s tool. Both were corrected to a working install path. See Installation for the current instructions
License of record was inconsistent — 2026-07-27
LICENSEis ISC while the workspace manifest declaredlicense = "MIT"; the manifest now says ISC