Skip to content

Execution Lifecycle

Execution lifecycle flow

Isolate::new(config) allocates a UID from the atomic bitset pool (60000-60999), creates a cgroup, and captures a baseline snapshot of the workspace.

execute_code_string() is language-aware:

  • Python: Writes source to a temp file, runs python3 <file>
  • C++: Compiles with g++ -O2 -std=c++17, runs the binary
  • Java: Compiles with javac, runs with java Main

The Supervisor clone()s into new namespaces. The Proxy fork()s the actual payload:

Supervisor (host)
└── Proxy (namespaced)
└── Payload (namespaced + chrooted + cgroup + seccomp)

If CPU or wall time expires, the Supervisor kills with SIGKILL immediately. Untrusted code doesn’t get a graceful shutdown.

After the payload exits, the Supervisor collects wait status, cgroup evidence, timing, and process lifecycle data. This evidence bundle is immutable once collected.

  1. Kill remaining processes in the cgroup
  2. Verify the baseline (workspace state matches snapshot)
  3. Remove the cgroup hierarchy
  4. Wipe the workspace (fd-safe, no symlink following)
  5. Release the UID back to the pool