> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xorcise.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Where XORCISE keeps its settings, the handful worth changing, and how to upgrade or remove an install without orphaning anything.

Most of XORCISE configures itself. The first `xorcise up` creates everything it needs and never overwrites what you have edited, which leaves a short list of things you actually set: a judge model, optionally a terrain model, the mission library switch, and ports if the defaults collide.

## What the first start creates

`xorcise up` checks its prerequisites before it writes anything, then bootstraps in order: it creates `~/.xorcise`, scaffolds `config.toml` and a `.env` file at mode `0600`, brings a fresh database to the current schema, provisions a local Headscale control plane with a self-signed TLS certificate, and starts the brain. Re-running `up` repeats the same path harmlessly — a scaffold is never overwritten, and provisioning is idempotent, so `up` also repairs a control plane whose containers disappeared after a reboot.

Everything lands under `~/.xorcise`, or under `XORCISE_HOME` if you set it before starting:

| Path               | What it holds                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
| `config.toml`      | Non-secret shape — role, host and port overrides — plus a managed Headscale block `up` appends and rewrites. |
| `.env` (`0600`)    | Every value the Settings page writes: model keys, model names, base URLs, token caps, the library switch.    |
| `xorcise.db`       | All durable state: agents, runs, results, grades, and the raw OpenTelemetry.                                 |
| `serve.log`        | The brain's stderr. This is the file to read when a start fails. It is truncated on every `up`.              |
| `logs/`            | Created, and empty. Nothing writes here.                                                                     |
| `missions/<slug>/` | Installed missions, their manifests, and their attachments.                                                  |
| `runs/<run_id>/`   | The derived event export for that run, rebuildable from the trace.                                           |
| `cache/tailscale/` | The pinned tailnet client, cached per architecture.                                                          |
| `headscale/`       | The local control plane's config, compose file, and its private CA and TLS certificates.                     |

One file in there is load-bearing and unmarked: `headscale/.owned`. It is the only thing that tells `xorcise down` that the running Headscale container and its volume belong to XORCISE. Delete it by hand and those resources are orphaned permanently — nothing will ever clean them up.

<Frame caption="The Settings page. Everything editable here is written to `~/.xorcise/.env`, never to `config.toml`.">
  <img src="https://mintcdn.com/xorciseai/73cVaorGzBMhO39b/images/settings.png?fit=max&auto=format&n=73cVaorGzBMhO39b&q=85&s=0f733ebef7ea53d08b07cc39db0c6bf4" alt="The Settings page showing the Evaluation, Mission Library and Runtime, and Diagnostics groups" width="2880" height="1800" data-path="images/settings.png" />
</Frame>

## Where configuration lives

Four sources feed one settings object. Highest wins:

```text theme={"theme":"css-variables"}
CLI flags  →  XORCISE_* environment  →  ~/.xorcise/.env  →  ~/.xorcise/config.toml
```

Two consequences are worth holding on to. A key set in both files is read from `.env`, not `config.toml`. And a `XORCISE_*` variable exported in your shell beats anything either file says, including for a CLI that is only talking to an already-running brain.

**The Settings page never writes `config.toml`.** Every value it can change is written to `~/.xorcise/.env` as a `XORCISE_MODEL_*`, `XORCISE_JUDGE_*`, `XORCISE_TERRAIN_*`, or `XORCISE_CATALOG_ENABLED` variable, and the file is re-chmoded to `0600` on every write. `config.toml` is world-readable and holds only non-secret shape, which is why the two are kept apart.

The page groups its cards under three headings: **Evaluation** for how runs are graded, **Mission Library & Runtime** for the catalog and your environment, and **Diagnostics** for system health and connection. Every field name below matches a card in one of those groups. For the exhaustive list of keys, types, defaults, and their environment-variable names, see [Configuration keys](/reference/configuration).

## Configure the judge model

The judge produces half of every score, and XORCISE ships no model. Bring your own OpenAI-compatible endpoint and key. Grading sends the distilled transcript of a run to whatever provider you point it at, so this is the setting that decides where your run content goes.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"theme":"css-variables"}
    xorcise config set-model --name gpt-4o-mini --key sk-... --base-url https://api.openai.com/v1
    ```

    Only the fields you pass change, and `--key ''` clears the key. Passing no options at all is a usage error rather than a silent no-op.
  </Tab>

  <Tab title="Web UI">
    Open **Settings** → **Judge model**, fill in **API key**, **Base URL**, and **Model name**, then choose **Save**. The card header shows **Not configured**, **Configured**, or **Connected**, and a masked hint of the saved key.
  </Tab>
</Tabs>

Either way the change applies to the next grade with no restart. Prove the key works rather than assuming it: `xorcise config test` calls the model and exits non-zero when it cannot, so it can gate a script, and the **Test** button on the card does the same thing. Test uses the *saved* key, not unsaved edits, so save first.

<Note>
  The key is write-only. Reading configuration back — over the API, in the UI, or with `xorcise config show` — returns only a four-character hint, never the key itself.
</Note>

## Bound the judge prompt

A long lab run can produce a judge prompt larger than the model's context window, at which point the judge half is unreachable and the score degrades to deterministic-only. Two caps exist for exactly that failure, and they are the controls to reach for before you change models.

The **per-span cap** defaults to 2000 tokens. It trims each span's body to a head-and-tail window with a marker in between, so every action survives while a few enormous tool outputs stop dominating the transcript. Setting it to `0` disables trimming.

The **pre-flight transcript cap** is off by default. Turned on, it rejects a run before the judge is called if the estimated prompt exceeds the ceiling. It is off deliberately: the local count is an estimate, so XORCISE prefers to let the call go through and surface the provider's real error than to reject a prompt that would have fit.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"theme":"css-variables"}
    xorcise config set-model --span-max-tokens 1000 --transcript-max-tokens 256000
    ```

    Pass `--transcript-max-tokens 0` to turn the pre-flight cap back off.
  </Tab>

  <Tab title="Web UI">
    On the **Judge model** card, set **Per-span token cap** directly. **Pre-flight transcript cap** is a switch; turning it on reveals a **Transcript token limit** slider covering 16,000 to 1,000,000 tokens and seeds it at 256,000.
  </Tab>
</Tabs>

Changing a cap affects the next grade. A run whose judge already failed does not need re-running — re-evaluate it and the sealed evidence is graded again under the new settings.

## Configure the terrain model

Terrain attribution maps each host and action on the terrain map back to the agent step that caused it, and it does that with a model call. By default it reuses your judge model and needs no configuration of its own. Override it only when you want attribution on a different model — each field you leave unset keeps falling back to the judge's.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"theme":"css-variables"}
    xorcise config set-terrain-model --name gpt-4o-mini --key sk-...
    ```

    Pass an empty string to clear a field and fall back to the judge model, and use `xorcise config test-terrain` to call whichever model is currently effective.
  </Tab>

  <Tab title="Web UI">
    Open **Settings** → **Terrain model**. The card shows the **Current model** and whether its **Source** is the judge configuration or a custom override. Fill in the **Override** block to change it, or choose **Use judge config** to clear the override.
  </Tab>
</Tabs>

Both routes report the effective model afterwards. Attribution also has a per-call transcript limit, defaulting to 256,000 tokens; an oversized batch is shrunk to fit rather than failed, so lower it only for a small-context attribution model.

## Connect the mission library

The hosted XORCISE library is free and needs **no API key, account, or sign-in of any kind** — the client sends no credential. A `catalog_key` setting exists and is read by nothing. Connecting it makes library missions appear in the catalog and pullable on demand, including automatically at run start; pulling one contacts the hosted catalog and a container registry, and sends nothing about your runs.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"theme":"css-variables"}
    xorcise catalog connect
    ```

    Use `xorcise catalog disconnect` to turn it off and `xorcise catalog status` to check it.
  </Tab>

  <Tab title="Web UI">
    Open **Settings** → **XORCISE Remote** and flip the switch. The card shows **Connected** or **Disconnected** and the catalog URL it is using.
  </Tab>
</Tabs>

Both write the same variable and take effect immediately. Read the result carefully: `xorcise catalog status` reports the saved setting and a live probe as two separate lines, and a saved preference is never reported as a verified connection. Disconnected means an empty remote library, not a stubbed one — your own ingested missions are unaffected.

## Change ports

XORCISE binds two planes: the REST API and web UI on `3001`, and the OpenTelemetry receiver on `4318`. There is no third plane. If a port is busy, `up` scans up to 50 ports above it, moves, and prints a notice per move — so read the address `up` prints rather than assuming the default.

To pin different ports, set them before starting — as a flag on `up`, or as keys in `~/.xorcise/config.toml`, which is a flat file whose keys are the setting names:

<CodeGroup>
  ```bash Flag on up theme={"theme":"css-variables"}
  xorcise up --port 3010 --otlp-port 4328
  ```

  ```toml config.toml theme={"theme":"css-variables"}
  rest_port = 3010
  otlp_port = 4328
  ```
</CodeGroup>

Sibling commands discover a relocated brain on their own, so `xorcise status` and `xorcise ui` keep working without being told. There is no web UI equivalent.

## Check your install

Three questions have three different answers: are the prerequisites on this host satisfied, are the ports answering, and what does the running instance believe about itself.

<Tabs>
  <Tab title="CLI">
    ```bash theme={"theme":"css-variables"}
    xorcise doctor
    ```

    `doctor` checks prerequisites and prints an exact fix per failure. `xorcise status` probes the REST plane, the OTLP plane, and the Docker daemon. `xorcise system` asks the running instance what it sees, including its role, topology, and database schema.
  </Tab>

  <Tab title="Web UI">
    Open **Settings** and read the **Diagnostics** group. The **Modules** card probes each module independently, grouped by service role, and the **Connection** card shows the **API endpoint** this browser is talking to and the **Access mode** in force.
  </Tab>
</Tabs>

The Modules card lists four modules: **REST API** under control, **Docker** under runner, **Headscale** under headscale, and **OTLP receiver** under collector. Each reads **Healthy**, **Down** with the probe's own detail, or **Not on this host** — which is a statement about your role, not a failure. Access mode has one live option, *Single operator · local trust*; the multi-user option is listed as coming soon and is not shipped.

The **Environment** card alongside them is read-only: your home path, the role and topology this process is running, and the database schema. When the schema reads **behind — migration needed**, the next section is what you want.

## Upgrade XORCISE

`up` brings a schema-less database to the current version, but it will not migrate a database that already has data. That refusal is deliberate: migrating populated data stays an explicit decision, so `up` stops with `database is behind the schema` instead of touching your runs.

```bash theme={"theme":"css-variables"}
xorcise down
pip install --upgrade xorcise
xorcise db upgrade
xorcise up
```

Nothing under `~/.xorcise` is destroyed by any of that — the package upgrade touches only site-packages, and `up` re-renders the Headscale config and re-provisions its container idempotently. Run `xorcise db upgrade` only when `up` tells you the database is behind; there is no downgrade path, so back up `xorcise.db` before rolling a version back.

If the migration fails with `migration history mismatch`, the database was stamped by a different build of XORCISE. Back up `xorcise.db`, then either run the build that created it or re-initialise from scratch.

## Uninstall XORCISE

Order matters here, and getting it wrong leaves Docker resources behind with nothing left on the machine that knows how to find them.

```bash theme={"theme":"css-variables"}
xorcise down --purge --yes
pip uninstall xorcise
```

The purge is what tears down the Headscale container, its network, and its named volume, reaps any leftover run containers, and removes `~/.xorcise`. Doing it after `pip uninstall` is not possible. XORCISE never removes Docker images, so reclaim those yourself with `docker system prune -a` when you are ready.

<Warning>
  `xorcise down --purge` deletes all of `~/.xorcise`, including your `.env` — which is the only copy of your model API keys — your database, and every run, result, and trace. It asks for confirmation unless you pass `--yes`.
</Warning>

## Related pages

<CardGroup cols={2}>
  <Card title="Configuration keys" icon="table-2" href="/reference/configuration">
    Every setting, its type, default, and environment variable.
  </Card>

  <Card title="Troubleshooting" icon="life-buoy" href="/operate/troubleshooting">
    Symptom-first fixes for start, run, and grading failures.
  </Card>
</CardGroup>
