Genie
Documentation

Updates & Channels

Install Genie once; thereafter builds flow over the air through release channels. Every update is cryptographically verified and staged separately from activation, so a download can never change the binary out from under a running session — and a bad build is one command to undo.

The model: install once, update via channels

After the initial install you never re-run an installer. New builds are published to three channels and the CLI moves between them on demand:

  • canary — the newest build. First to receive changes; least baked.
  • beta — a build promoted out of canary for wider testing.
  • stable — the safest, fully promoted build. The default channel.

Updating is deliberately a two-step process: genie update downloads, verifies, and stages a build; genie use is the separate, explicit step that activates it. Genie never auto-swaps the active build during an update — a background update silently changing the binary mid-session is exactly the footgun this design avoids.

Inspect the active build

genie channel shows which build is currently active — version, install path, git branch/sha (when run from a worktree), and the pipeline manifestSha.

genie channel

  version:     1.x.x
  worktree:    /Users/you/.genie/versions/sha-...
  branch:      unknown
  gitSha:      unknown
  manifestSha: sha-...

genie update — download, verify, stage

genie update resolves the newest build on your channel (or an exact build with --sha), downloads it, runs the full verification chain, and extracts it into ~/.genie/versions/<sha>/. It does not activate the staged build — it prints the exact genie usecommand to run when you're ready.

# Stage the newest build on your channel (stable by default)
genie update

# Target a specific channel
genie update --channel beta

# Pin an exact published build
genie update --sha sha-<40hex>

# After staging, Genie tells you exactly how to activate:
#   Verified + staged sha-... → ~/.genie/versions/sha-...
#   Activate when ready:  genie use stable

Exit codes are scriptable: 0 staged or already current · 1 nothing to do (channel check skipped) · 2 resolve/network failure · 3 verification or extraction failure — the security-relevant one, kept distinct so CI and wrappers can alert on it specifically.

genie use — activate, rollback, list, gc

genie use performs an atomic swap of the active build. Because activation is a rename of a fully-extracted directory, a crashed or half-finished download can never become the selected version — the swap only ever points at a complete build.

# Switch the active build to a channel or an exact sha
genie use stable
genie use sha-<40hex>

# Instantly revert to the previous build
genie use --rollback

# List installed builds (* = active, (prev) = rollback target)
genie use --list

# Reclaim disk — remove builds older than the last 10
genie use --gc
genie use --gc --yes
  • genie use <channel|sha> — switch to a channel's current build, or an exact sha-<40hex>.
  • genie use --rollback — instantly switch back to the previously-active build. Zero download; pure local swap.
  • genie use --list — show installed builds; * marks the active one, (prev) the rollback target.
  • genie use --gc — remove builds older than the most recent 10 (the active and previous builds are always protected). Add --yes to skip the confirmation prompt.

Channel names resolve via ~/.genie/channels.json, which genie update populates. If you run genie use beta before any genie update, Genie tells you to fetch the channel manifest first.

The safety story

Every staged build clears a layered verification chain before it can be activated:

  • SHA-256 integrity gate — the downloaded tarball's hash must equal the manifest's artifactSha256. Catches truncation and CDN corruption cheaply.
  • minisign signature — the cryptographic trust root. The artifact and its build metadata (the trusted comment) are both Ed25519-verified against your configured public key. Pure-Node, no native deps, works fully offline (air-gapped fleet, on a plane).
  • Fail-closed — if no trusted key is configured, genie update refuses to install. There is no "trust on first use".
  • Atomic activation — staged into a temp dir, then renamed onto the version path. A half-written extract is never selectable.
  • Instant rollbackgenie use --rollback reverts to the prior build with a local swap, no network.
Scope, honestly. A Sigstore SLSA provenance bundle is fetched alongside each build and its presence is asserted, but full identity-pinned Sigstore verification (matching the certificate identity to the publish workflow) is a documented future enhancement, not enforced today. minisign is the current cryptographic trust root. This is already strictly stronger than the sha256-only verification many other CLIs ship.

Environment knobs

# Silence the non-blocking startup "newer build available" check
export GENIE_NO_UPDATE_CHECK=1

# Trusted minisign public key — required for 'genie update' to install
export GENIE_MINISIGN_PUBKEY="RWQ..."
  • GENIE_NO_UPDATE_CHECK=1 — silence the non-blocking startup check that tells you when a newer build is available on your channel. The check is already skipped automatically on non-interactive terminals and in CI; it caches the channel manifest for 24h so the origin sees roughly one probe per box per day, and it never blocks or delays your command.
  • GENIE_MINISIGN_PUBKEY — the trusted minisign public key used for signature verification. genie update refuses to install any build without it (fail-closed).

See also

For the full command reference, see the CLI docs.