<!-- SPDX-License-Identifier: Apache-2.0 -->

# Upgrades

CireilClaw applies configuration migrations automatically when a new version starts.

Migrations update configuration files and persisted session data to match the new version's schema.

## Before upgrading

1. Back up the complete runtime root.
2. Read the release notes for the target version and note any manual steps.
3. Restore the backup to a scratch path and run the currently installed binary's `cireilclaw --root <PATH> dry-run` to confirm the pre-upgrade configuration is valid. The upgraded binary may reject legacy keys until its migrations have run.

## Using the published updater

Configure the public Forgejo repository in `config/system.toml`:

```toml
[updater]
repository = "https://git.example.test/owner/cireilclaw"
```

Use `cireilclaw update check` to see whether a newer stable release is available.

Use `cireilclaw update latest` to inspect the selected release, archive, size, and checksum.

Use `cireilclaw update install` without a version to discover, stage, and verify the highest valid stable release from the selected repository, then confirm the replacement.

Pass `--repository <URL>` for a one-invocation source override, or pass an exact stable version to `update install`.

The updater is Linux x64-only and requires the invoking executable to be a writable published `CireilClaw` binary.

Stop all agents and channels before installing or rolling back, because `run` and every mutating command hold the shared runtime-root mutation lock. Published executable operations also hold an installation-scoped lock, so another runtime root cannot replace the same executable concurrently.

The updater retains exactly one previous executable at `<executable>.old`.

## During upgrade

The updater does not run configuration migrations during installation.

Migrations run automatically when the new version starts, or can be applied explicitly with `cireilclaw migrate`.

Every file changed by a migration is backed up under `config/backups/<migrationId>/` before it is modified.

## v2.0.0 editing tool migration

`str-replace` is removed from the built-in registry. Migration `20261014000000_replace_str_replace_with_edit` removes that key from each agent's `config/tools.toml` and sets `edit` to `true` if either the old `str-replace` or existing `edit` setting was `true`; if both were disabled, editing remains disabled. Invalid non-boolean values stop the migration rather than being normalized. The original configuration is backed up before rewriting.

The migration runs before agent composition at startup. To inspect and apply it explicitly with the upgraded binary, run:

```sh
cireilclaw migrate --root PATH --dry-run
cireilclaw migrate --root PATH --mode run-all
cireilclaw dry-run --root PATH
```

`dry-run` validates configuration but does not apply migrations, so an unmigrated `str-replace` key is rejected even when its value is `false`. For manually maintained configurations, remove `str-replace` and set `edit` to the intended enablement value.

Update custom agent instructions, plugins, and integrations to call `edit` instead of `str-replace`. Use the provider-facing `edits` array with `oldText` and `newText` rather than the old tool's top-level `old_text` and `new_text`:

```json
{
  "path": "/workspace/example.txt",
  "edits": [
    { "oldText": "before", "newText": "after" }
  ]
}
```

`edit` uses fuzzy whitespace matching, not the old tool's exact literal matching. Use `near` to disambiguate matches or `dryRun` to preview a change before applying it. Its result exposes `success`, a `patch`, and edit metadata rather than the old tool's `context` excerpt. Existing agent instruction files are not rewritten automatically.

For remote adapters, replace `str-replace` with `edit` in operator grant files' `harnessTools` arrays and apply the updated grants with `remote update-grants`; the tool-configuration migration does not change persisted adapter grants. Historical tool-call records retain their original names and results, but the removed built-in cannot be invoked or enabled.

## v2.0.0 context-budget migration

`maxTurns` is removed from provider configuration and no longer limits visible history. Migration `20261014010000_remove_max_turns` removes the key from provider tables in both global and agent `config/engine.toml` files, preserving other provider settings and per-model overrides. Invalid legacy values stop migration rather than being silently discarded. The original configuration is backed up before rewriting.

Pruning now always uses a token budget. The runtime chooses an explicit per-model `contextWindow`, otherwise provider metadata, otherwise a 128000-token fallback. Before starting models with smaller windows and unavailable metadata, set their actual `contextWindow` in `[<provider>.models.<model>]`; do not translate the old turn count into a token count. See [engine configuration](../configuration/engine.md#per-model-overrides).

Use the migration inspection and application commands above before running `dry-run` with the upgraded binary. An unmigrated `maxTurns` key is rejected by configuration loading. For manually maintained configurations, remove it and configure per-model context windows where necessary.

For C# integrations, remove `ProviderConfiguration.MaxTurns` and `ProviderConfiguration.DefaultMaxTurns` references. Replace `Pruner.TruncateToTurns` calls with `Pruner.TruncateToBudget` using a token budget. `Pruner.PruneHistory` no longer takes a turn-count argument and requires a non-null context window; resolve the window first and use `Pruner.DefaultContextWindow` only when no configured or provider window is available.

## v2.0.0 scheduled-job validation

Before upgrading, inspect each agent's `config/cron.toml` for jobs combining `execution = "main"` with `delivery = "webhook"`. That combination previously sent successful responses to the session channel rather than the webhook and is now rejected, including for disabled jobs. Change `execution` to `"isolated"` to deliver the captured response to the webhook, or change `delivery` to `"announce"` or `"none"` to retain main-session execution. Apply the same correction when recreating any persisted dynamic job with that combination; invalid persisted jobs are skipped with a scheduler warning.

Every job with `delivery = "webhook"` must also supply an absolute `webhookUrl`; a missing URL is now a configuration error rather than a failed delivery after execution. Add the intended URL or change `delivery` to `"announce"` or `"none"`. Correct this field when recreating affected persisted jobs as well.

`dry-run` now checks heartbeat and cron configuration, cron-expression syntax, and tool names against the loaded built-in/plugin registry. Runtime startup also rejects unknown tool names before starting that agent's channel. Correct invalid schedules and unknown tool keys, including disabled unknown tools, then run `dry-run` against the upgraded binary before starting the host.

For C# integrations, replace calls to the removed `RuntimeScheduler.ScheduleDynamic(job)` with `await RuntimeScheduler.ScheduleAsync(job, cancellationToken)`. This is the persistence-and-worker admission boundary; do not separately upsert the same job before calling it. The scheduler owns a configuration snapshot, and remote reminders receive a persisted revision that fences replaced workers.

## v1.4.0 message-table migration

Starting v1.4.0 automatically migrates each agent's persisted session history from the `sessions.history` JSON column into ordinal rows in a new `messages` table, with durable channel message identities in `message_channel_ids` and deduplication records in `discord_ingested_messages`. The migration is idempotent and preserves existing history. The `messages` table becomes the durable copy of history, so `sessions.history` is rewritten to cover only the post-prune suffix once pruning has run. Downgrading the executable alone is insufficient: v1.3.0 reads only `sessions.history` and would lose history pruned before the downgrade. To downgrade, stop the runtime and restore the complete pre-upgrade runtime-root backup together with the older executable. Restoring that backup discards runtime changes made after the backup.

## v1.3.0 media migration

Starting v1.3.0 automatically migrates each agent's legacy `images/` cache directory to `media/` and its SQLite image index to the unified media index. The migration is idempotent and preserves existing image data without manual configuration changes. Back up the complete runtime root before starting the new version. After migration, v1.2.0 does not understand the new media layout, so executable rollback alone is insufficient. To downgrade, stop the runtime and restore the complete pre-upgrade runtime-root backup together with the older executable. Restoring that backup discards runtime changes made since the backup.

## Rollback

Use `cireilclaw update rollback` to atomically exchange the current executable with `<executable>.old`.

Executable rollback does not restore configuration files, migration markers, databases, agent data, or credentials.

If a new executable starts and migration fails, the new executable remains current and `.old` remains available for manual recovery.

## After upgrading

Run `cireilclaw --root <PATH> dry-run` against a copy of the migrated runtime before activating it.

If a migration fails, diagnose from the logs and restore from backup before retrying.
