# Updates, reconcile, recovery

This page covers the internals behind [Update and recover](/docs/guides/updates-and-recovery/): how updates install, which images rebuild, and how Speedwave recovers containers. These flows run on macOS (Lima VM) and Windows (WSL2), not Linux.

## Update, reconcile, rebuild

`install_update_and_reconcile(expectedVersion)` records the running projects, stops their containers, installs the approved version, and restarts. If install fails first, Speedwave restores the stopped projects and keeps the previous install running.

After restart, the backend compares the installed bundle's `bundle_id` against the id last applied. A mismatch triggers a reconcile, persisted as a state machine so an interrupted update resumes cleanly: sync `claude-resources`, build any image missing its hash tag, then recreate (`--force-recreate`) the projects that were running before the update.

`bundle_id` only gates whether resources sync and projects restart. Each image rebuilds independently, keyed by its own tag hashed from its Containerfile and sources:

| Trigger | Effect |
| --- | --- |
| Missing hash tag | Rebuilds that image alone |
| Shared MCP server change | Rebuilds every dependent worker |
| `claude-resources` change | Rebuilds nothing, still triggers reconcile |
**Note:** The hash covers build inputs, not image content: base images like `node:24-*` stay external and mutable.

Reconcile and setup build lazily, per project: enabled integrations for the active project get images. A fresh setup with no active project still builds `speedwave-claude`, `proxy`, and `speedwave-mcp-hub`.

## Recovery

Speedwave auto-recovers stale containers after sleep/resume and missing containers after a containerd restart or VM recreation. `ensure_exec_healthy` runs before an interactive session starts, targeting the project's Claude container (see [Container topology](/docs/under-the-hood/container-topology/)): it probes with an exec check, force-recreates on a stale-mount or missing-container error, then probes again, failing with "Please restart Speedwave" if that fails.

On Windows, a lower-level check covers the WSL2 distro itself: Speedwave verifies containerd and buildkitd before a session starts, auto-starting either with bounded retries. If that fails, escalating paths restart both units, and last resort resets the distro (terminate, then unregister), the same reset behind the Factory Reset action in Desktop settings.

## The CLI update path

`speedwave update` ([CLI commands](/docs/reference/cli-commands/)) fixes filesystem permissions, runs [a mandatory security check](/docs/security/securitycheck/) (nothing saves unless it passes), builds only the missing images, recreates containers, and verifies they came up, failing loudly if none did. It then prunes superseded image tags, never the build cache.

If the update fails after containers are torn down, Speedwave restores the pre-update snapshot. It prefers the exact snapshot but falls forward to a fresh compose render if the snapshot predates a newer security rule; only if both fail does rollback abort, printing the violations. Disk space is reclaimed only after a full restore succeeds. For code signing, see [Binary authenticity](/docs/security/binary-authenticity/).