# Upgrade

Upgrade basalt and the guard in your database with basalt upgrade. It never touches your agent's password, grants or passkeys.

A new version of `basalt` can ship changes to the guard that lives in your Postgres. `basalt upgrade` brings the guard up to date. It does not touch anything else.

Use it when:

- `basalt status --agent NAME` says an upgrade is available or required.
- The agent gets a `GUARD_UPGRADE_AVAILABLE` warning, or an `UNAVAILABLE` error with the reason `GUARD_OUTDATED`.
- The engine logs `guard schema vN is older than this build's vM`.

## 1. Install the new basalt

Install the new version the way you installed the first one. See [Install](/start/install/). Check it:

```sh
basalt version
```

## 2. Upgrade the guard

```sh
basalt upgrade --agent NAME
```

The command reads the guard version with the agent's own credential. Then:

1. If the guard is current it says `basalt: the guard is up to date (version N); nothing to upgrade` and stops. Nothing else is asked.
2. Otherwise it asks for the admin connection string at a hidden prompt, or reads `BASALT_ADMIN_DATABASE_URL`. It is used once and never stored. The command refuses a string that points at a different database than the agent's.
3. It prints what it will do and the SQL:

   ```text
   This upgrades Basalt's guard from version 18 to 21; no agent changes.
   ```

4. It asks `Run this? [y/N]`. Answer `y`. Add `--yes` to skip the question, or `--dry-run` to print the SQL and stop.

The upgrade runs in one transaction. The numbers in the example are for illustration.

It adds only the guard's migrations that your database lacks. It never rotates the agent's password, adds no policies, registers no passkey, and the engine needs no restart for it. Add `--config PATH` if the engine runs from a config that is not the default.

## 3. Check it

```sh
basalt status --agent NAME
```

It reports the guard version against the build, and lists any problem with the command that fixes it. A stopped engine that missed a breaking migration serves only `status` until you upgrade. After the upgrade it serves normally again with no restart. A guard that misses only a non-breaking migration is served normally, with a `GUARD_UPGRADE_AVAILABLE` warning.

To run the new binary, restart the engine. As a Linux service:

```sh
sudo systemctl restart basalt-engine.service
```

On macOS, `sudo launchctl kickstart -k system/dev.basaltdb.engine`. Then start a new agent session, so the agent loads the current tool descriptions.

## When it stops

- The guard is not installed: that is the job of `basalt init`, not `upgrade`. See [Install](/start/install/).
- The guard is newer than this build: install a newer `basalt`.
- It refuses to run on an engine your bot operates, because it would ask for your admin connection string on the bot's machine. The bot runs `basalt init --remote`, which makes an upgrade code, and you run it on your own computer with `basalt init --setup-code CODE`. See [A bot on its own computer](/guides/bot-own-computer/).
- It says the connection string names a different database: use the admin connection string of the database the agent uses.

Run `basalt init` again only if you also want to change a flag, such as the agent's tables. See [Install](/start/install/).

## Next

- [Remove BasaltDB](/guides/remove/): the opposite direction.
- [Errors](/reference/errors/): `GUARD_OUTDATED` and `GUARD_UPGRADE_AVAILABLE`.
