A team's self-hosted CI runner executes untrusted pull-request builds directly on the host, sharing a filesystem and process table with every other concurrently running job, "because containers add overhead." What specifically goes wrong, and what do namespaces and cgroups actually provide that a shared host cannot?
"A job is a fresh machine" isn't a metaphor for a hosted runner, and it isn't optional for a self-hosted one either: a GitHub-hosted runner is a short-lived VM provisioned from a clean image and destroyed after the job, so nothing a previous job wrote to disk, installed, or left running survives into the next one. Running jobs directly on a shared host, with no container between them, throws that property away — one job's leftover environment variable, background process, half-written file, or a secret injected into its environment is all readable or interferable-with by any other job running on the same host at the same time, which is a real problem specifically because a pull request from a fork runs code the team did not write. Containers (or VMs) give each job its own PID namespace (it can't see or signal another job's processes), its own mount namespace (its own filesystem view), and its own network namespace, with cgroups capping how much CPU and memory it may use — none of this is about speed, a persistent shared box runs the actual build steps just as fast; it's specifically about not letting one job's state, or one job's malicious code, reach another job's.