Skip to main content
This page is for contributors working from a clone of the XORCISE repository. The evaluation loop itself — up → register → mission → run → prompt — is the same one every user walks, and Your first run explains each step; this page covers only what is different from source: the install extras, the fused base image, stub mode, and the failure modes a development checkout produces. General failures are on Troubleshooting.

Prerequisites

  1. Docker Engine running, and the runner extra installed: uv pip install -e ".[runner]" (or ".[all]"). A plain pip install xorcise covers the default single-host setup.
  2. The fused base image xorcise/mission-base — the local fused-image build produces it automatically if it is absent (from the bundled context under containers/mission-base). Build it ahead of time only if you want to control when that happens:
    The base installs Tailscale, so the build needs egress to tailscale.com.
  3. A mission — pull one from the mission library: xorcise mission list, then xorcise mission pull <id>. The library is free, and pulling needs no account and no key.
Installing your own mission bundle is coming soon. In this release xorcise mission ingest is a stub — whatever arguments you pass it, it prints a coming-soon notice and exits without installing anything — and the Ingest a bundle button on the Missions page opens a product preview rather than a directory picker. Missions come from the library instead: xorcise mission list and xorcise mission pull <id>, or that same Missions page. The bundle format still holds if you want to prepare one ahead of time — a directory with mission.json + docker-compose.yml + service Dockerfiles, as in the samples under missions/ in the repository.
xorcise up provisions the local Headscale control plane itself (and xorcise down tears it down); an external control plane can be pointed at via the headscale_url setting instead.
To walk the flow without Docker, use xorcise up --stub (or XORCISE_USE_STUBS=1) — the loop then runs against stubs and no container actually starts. A role that needs Docker but cannot reach it fails loudly at boot — it never silently falls back to stubs.

The loop

What “real” looks like

  • Installing a mission puts a real fused image on the host and writes the install record — no registry needed at run time. The local build engine behind that (the POST /missions/ingest API, which the coming-soon CLI and console surfaces will drive) builds xorcise/mission-base if it is not already present, then builds the inner stack into a fused xorcise/mission-<slug>:<ver> image.
  • run create starts a real container (docker ps shows it), and the network fence mints a one-time pre-auth key and applies the per-run ACL — the agent can reach exactly its one mission.
  • run prompt carries a live tailnet join recipe, the authenticated run-control REST URL + per-run key, and the target(s) — everything the agent needs to join and work the mission.

If something fails

  • Boot errors “Docker daemon is not reachable” / “requires the ‘runner’ extra” — install the extra / start Docker, or use --stub for a Docker-less walkthrough.
  • The base image build fails — it needs egress to tailscale.com. On a restricted network, pre-build xorcise/mission-base from a host with egress (or an offline mirror) so the build finds it already present.
  • mission pull fails — check the catalog connection (xorcise catalog status). Pulling is how missions arrive in this release, so it needs network access to the mission library; a fully disconnected host cannot install one.
  • A CLI command says it cannot reach the server, but the server is up — the server may have relocated to a free port; always use the URL xorcise up printed (or run xorcise ui), and don’t hardcode :3001 in scripts.
  • mission pull succeeds but mission list / run create don’t see it — the server and your shell are using different homes. Don’t set XORCISE_HOME (both default to ~/.xorcise), and kill any stale server before xorcise up.
  • xorcise doctor reports Docker presence/daemon and port conflicts.
Everything else — Docker socket permissions, database migrations, telemetry correlation, grading — fails the same way from source as from an installed package: see Troubleshooting.