Skip to main content
Everything you used in your first run is one long-lived process on your machine plus a handful of Docker containers. Nothing else is installed, and no server is involved.

What you’ll learn

  • What xorcise up starts, and which piece answers your browser, your CLI and your agent.
  • How your agent reaches a deliberately vulnerable mission without that mission reaching your host.
  • Where a run’s data lives, and which parts of a run leave your machine.

The local architecture

One process serves two network planes. Docker holds the mission. Your agent runs outside all of it and talks to both. The process is what xorcise up starts in the background. It writes its own errors to ~/.xorcise/serve.log, holds all durable state in a single SQLite file, and drives Docker over the local socket. It does not reach out to anything on its own.

The planes

The process listens on two ports, and they answer completely different audiences. Both ports auto-increment when the one they want is busy, scanning up to 50 ports above it and printing each move. Treat the numbers above as defaults rather than facts about your install: the authoritative values are the ones xorcise up prints, and xorcise status reports them again later.
In the default local topology both planes bind loopback — 127.0.0.1 and ::1 — plus, on native Linux, the Docker bridge gateway, which is how an agent running in a container reaches them through host.docker.internal. The bind widens to 0.0.0.0 only if you set XORCISE_HOST=0.0.0.0, or on Linux when the bridge gateway cannot be determined at boot. Neither plane has any authentication, so every process on your machine and every container on that bridge can already read your runs and create new ones — and widening the bind extends that to anyone who can reach the port. Security and isolation covers what to do about that.

How a run reaches its mission

A mission is deliberately vulnerable software, so XORCISE never puts it on a network your host can route to. Each run gets its own isolated network instead, built from two pieces. The first is topological. The mission’s containers run on a Docker network nested inside a container of their own, so there is no route from your host to a mission address. The second is a private tailnet: XORCISE mints a one-time key per run, and a Headscale policy grants exactly one rule — this run’s agent may reach this run’s addresses, and nothing else. There is no default-allow rule, so the policy is fail-closed, and XORCISE refuses to apply a policy that does not match that shape. Two runs in flight at once cannot see each other’s targets. You never configure any of this. It is created when the run is created and torn down when the run seals; the connect prompt hands your agent the one command that joins it.
Be clear about what this does not do. It is not an egress firewall and it is not a Docker internal network. The mission containers sit behind ordinary NAT, so traffic from a mission target out to the internet is not blocked. The isolation guarantee is that the mission is unreachable from your host and from other runs — not that the mission is sealed off from the world.

What happens from create to score

One path, from the moment you create a run to the moment a number exists. Two details are worth carrying forward. The evidence is sealed at completion — telemetry that arrives after that point is rejected rather than folded in, which is why the launch profile has to be exported before the agent starts. And the judge call is the only step in this sequence that leaves your machine; pulling a mission and attributing terrain also reach off the host, and the table below accounts for all three.

Where things are stored

Everything lives under ~/.xorcise, or wherever XORCISE_HOME points. That last row matters when something goes wrong: logs/ exists but has no writer anywhere in XORCISE, so a stuck start leaves no trace in it. Read serve.log instead.

What runs where

The third row is short but real. Pulling a mission contacts the hosted library and downloads its image; it needs no account, no API key and no sign-in, and it sends nothing about your runs. Judging and terrain attribution both send a distilled transcript of the run — what your agent did — to the model provider you configured, using your key. Everything else stays on the machine, and there is no analytics of any kind. Security and isolation sets out exactly what each of those three sends.

Next steps

The next five pages take the pieces apart in the order a run uses them: agents, missions, runs, traces, and grading.

Agents

The agent record, and the one decision it forces.