What you’ll learn
- What
xorcise upstarts, 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 whatxorcise 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.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.