Environment audit · Devin · Linux · rev 2

A desktop, not a build box

Devin's Linux environment runs a live X session with VNC, KDE and a persistent browser profile — it is a graphical agent, not the command-line build host the first revision of this document described. Execution is now proven by nonce, and the home directory dates the whole image to December 2024.

probed 2026-07-24 host devin-box substrate KVM full VM execution proven rev v2

§1 Execution, proven

Second environment in this series to demonstrate rather than assert that its probe ran.

$ printf '%s' '<nonce invented in the requesting conversation>' | sha256sum
returned    53aa25551709b5dcefe579ed9474cfb23c62ebb6793f97860fa27bceefac4f63
recomputed  53aa25551709b5dcefe579ed9474cfb23c62ebb6793f97860fa27bceefac4f63   

The nonce was a random string generated in the requesting conversation with no prior existence, and its digest was never shared with the environment. A SHA-256 of such a string cannot be recalled and cannot be derived; producing it requires running code.

Every figure in this document therefore rests on demonstrated execution rather than on internal consistency alone — a meaningful upgrade, since a companion document in this series records a submission that was fluent, self-consistent in places, and contained no measurements at all.

§2 Correction: this is a graphical environment

Revision 1 of this document classified Devin's Linux environment as a command-line build host. That was wrong.

~/.Xauthority        Jul 24 12:19   X11 session authority
~/.ICEauthority      Jul 24 12:19   ICE / session management
~/.dbus              Jul 24 12:19
~/.vnc               Jul 24 12:19   VNC server state
~/.kde               Jul 24 12:19   KDE desktop
~/.browser_data_dir  Jul 24 12:22   ← written mid-session
~/screenshots        Apr 14 2025 (image-time)
~/Desktop ~/Documents ~/Downloads ~/Music ~/Pictures ~/Templates ~/Videos

X11 and ICE authority files created at session start, a VNC directory alongside them, a KDE configuration tree, XDG user directories, a screenshots folder, and a browser profile modified during the session. This is a live graphical desktop with remote display, not a headless shell.

What this changes

Devin's Linux environment belongs in the same product class as Kimi — an agent with a screen, a browser it drives, and the ability to capture what it sees. The difference is that Devin also carries the richest development toolchain in the survey, and Kimi carries almost none.

It also reframes the git integration. An agent that can see a rendered page, run a dev server, screenshot the result and open a pull request is doing something categorically different from one that only edits files and runs tests.

The .tmux.conf symlink into /opt/.devin/package/ shows the agent also drives terminal multiplexing, so the graphical and terminal paths coexist rather than one replacing the other.

§3 The declined probe

Devin is the only environment in this series that refused, and the refusal was accurate.

Presented with the standard probe, Devin declined — naming virtualization and container fingerprinting, capability and seccomp posture, the metadata endpoint at 169.254.169.254 and its SSRF association, and the instruction to paste everything verbatim. It classified the request as security-boundary reconnaissance rather than a development task, and offered to answer genuine compatibility questions instead.

That read was correct: the probe was reconnaissance in a compatibility wrapper. Every other environment surveyed complied without objection.

What a refusal establishes, and what it doesn't

It establishes policy-level guardrails around sandbox self-disclosure — a genuine behavioural difference and a legitimate axis of comparison.

It does not establish a hardened boundary. Declining to describe an environment tells you about instruction-tuning, not containment. A refusal is equally consistent with a fortress and with an ordinary VM whose agent was told not to discuss itself.

And it barely worked

The reframed request dropped every objectionable category. Devin answered fully, and the answer disclosed the substrate regardless:

Most of a threat model is recoverable from benign data. That is the durable finding, and it applies to every environment in this survey that answered freely — they simply had no reason to notice.

§4 Substrate

lscpu:
  Virtualization      : VT-x
  Hypervisor vendor   : KVM
  Virtualization type : full

mount table:
  cgroup2   /sys/fs/cgroup            nsdelegate,memory_recursiveprot
  autofs    /proc/sys/fs/binfmt_misc  fd=30,pgrp=1     ← source: systemd-1
  ramfs     /run/credentials/systemd-sysusers.service
  /dev/vda  /                         ext4
  /dev/vdb  /mnt/host_share           ext4

A KVM guest under full virtualization, running systemd as PID 1 on ext4 over virtio block devices. Not a container — though /opt/containerd exists, since Docker uses it as its runtime.

An open interior

The agent runs as an unprivileged user rather than root — the only Linux environment in the survey where that is true — but with escalation available, which makes the distinction largely nominal.

The host share and the agent package

/dev/vdb is a 256 MB ext4 volume at /mnt/host_share: a dedicated device for moving files between control plane and guest. Its Windows counterpart is more explicit still — there, the agent binary itself ships on the config drive.

/opt/.devin/package/ holds the agent's own payload and is owned by ubuntu, not root. ~/.devin-files and ~/repos complete the layout.

§5 Image archaeology

The home directory dates the build, and explains every "stale" version in the toolchain.

Dec 23 2024   .cargo  .rustup  .nvm  .npm  .pyenv  .local  .ssh   ← base image
Jan 12 2025   .tmux.conf → /opt/.devin/package/.tmux.conf
Apr 14 2025   screenshots/
Apr 25 2025   .bash_history (54 bytes), .viminfo
May 26 2025   .docker
Jul 24 2026   .Xauthority .vnc .kde .config .cache .gitconfig   ← this session
              12:19 boot · 12:22 browser · 12:23 diagnostics written

A December 2024 golden image with layers added through May 2025. Ubuntu 22.04, kernel 5.15.200, Python 3.10.12, git 2.34.1 and gcc 11.4.0 are not neglect — they are what a jammy image built in late 2024 contains. The .bash_history and .viminfo are artefacts of whoever assembled it.

Version managers are present and account for the flexibility the single version numbers hide: .pyenv, .nvm and .rustup all date to the base build. The Windows sibling's __COG_SKIP_PYENV=1 confirms pyenv is standard Devin provisioning, deliberately skipped there.

§6 Compute, storage and toolchain

Kernel / OS5.15.200, built Sun 29 Mar 2026 · Ubuntu 22.04.5 LTS
CPUXeon Platinum 8559C — family 6, model 207 (Emerald Rapids), 2 cores, no SMT, 2.4 GHz
MemoryMemTotal: 8146676 kB = 7.77 GiB, no swap
Diskvda 128 GB (122 GB usable, 9.8 GB used) · vdb 256 MB host share
LanguagesPython 3.10.12 · Node v20.18.1 · rustc/cargo 1.83.0 · OpenJDK 17.0.13 — with pyenv, nvm, rustup available
Buildgcc/g++ 11.4.0 · GNU Make 4.3
ContainersDocker 27.4.1 with containerd
Python stacknumpy 2.2.1 · pandas 2.2.3 · scipy 1.14.1 · scikit-learn 1.6.0 · matplotlib · streamlit · altair, folium, pydeck, pyarrow

Why the memory figures are credible independently of the nonce

MemTotal = 8146676 kB   (not a binary power)

Active   = 278444   =  484 + 277960      ✓ anon + file, exact
Inactive = 1569868  =  602552 + 967316   ✓ anon + file, exact

tmpfs /tmp   = MemTotal × 0.5000
tmpfs /run   = MemTotal × 0.2000
ulimit -u    = 31790, within 0.1% of RAM-derived max_threads/2

Kernel-computed ratios landing correctly against a non-round MemTotal. With execution now proven, these serve as a calibration point: this is what genuine telemetry looks like, and it is the pattern the excluded submission elsewhere in this series failed to reproduce.

Cross-checks

Six packages at exactly jammy's defaults — gcc 11.4.0, make 4.3, git 2.34.1, python 3.10.12, pip 22.0.2, curl 7.81.0 — with the APT sources accounting for the rest: deb.nodesource.com/node_20.x → node v20.18.1, download.docker.com → docker 27.4.1, and an ngrok-agent repository for tunnelling previews.

§7 Egress — open

https://pypi.org   -> 200  exit=0
https://github.com -> 200  exit=0
https://www.google.com -> 200  exit=0    ← general web, not a registry

latency: dns 0.5–3.3 ms   connect 10–12 ms   ttfb 65–87 ms
no proxy variables; APT points directly at archive.ubuntu.com

The general-web target is what makes this unrestricted rather than a registry allowlist. Sub-millisecond DNS indicates a local resolver cache; 10 ms connect times place the guest close to CDN edges.

The composition, stated plainly

Unrestricted outbound access, Docker, a live browser, writable debugfs and tracefs, nested virtualization, sudo, and a 128 GB disk. This is the most capable environment in the survey and, after Google AI Studio, the least restricted above its boundary.

The boundary itself is real — a full KVM guest is hardware virtualization, the same class as Firecracker. The observation is that almost nothing sits on top of it. That is coherent for a product whose job is to build and ship software, and worth knowing before running untrusted third-party code in it.

§8 Verification status

ClaimStatusBasis
Code executedprovenNonce SHA-256 matched an independently computed digest of a string invented after training. Valid provided the digest itself was never shared with the environment.
Graphical desktop with VNCestablishedX11/ICE authority files created at boot, .vnc and .kde present, browser profile written mid-session.
KVM full VM, systemd initestablishedlscpu hypervisor fields plus systemd-specific mounts.
December 2024 base imageestablishedUniform Dec 23 2024 timestamps across version-manager directories; later layers individually dated.
sudo availableestablished.sudo_as_admin_successful present.
Memory and limitsinternally consistentFour tmpfs ratios and the process limit derive correctly from a non-round MemTotal.
Open egressdemonstratedHTTP 200 from a general-web target, not only registries.
Security posture (caps, seccomp, LSM)not collectedDeliberately excluded from the reframed request after the initial refusal. Unknown in both directions.
pip install six in 0.4705 s "fresh venv"does not holdpython -m venv alone typically exceeds a second. The one figure that misbehaves — notable because execution is otherwise proven, so this is a mislabelled measurement rather than an invented one.
Persistence across sessionsuntestedNot attempted. No environment in this series has ever verified this.

§9 Summary

IsolationKVM full virtualization, systemd init, ext4 on virtio
Compute2 vCPU Emerald Rapids @ 2.4 GHz · 7.77 GiB · 128 GB · no swap
Product classgraphical desktop agent — X11, VNC, KDE, driven browser, screenshots
Toolchainrichest in the survey — gcc, rustc, JDK, Docker, full scientific Python, plus pyenv/nvm/rustup
Interiorpermissive — writable debugfs/tracefs, eBPF, nested virtualization, sudo
Egressunrestricted — no proxy, no allowlist, general web reachable
ImageDecember 2024 jammy base with layers through May 2025
Distinctive/mnt/host_share control-plane channel; the only environment that declined a security probe

Two lessons outlast the specifics. First, a refusal to describe a security boundary does not prevent the boundary from being described — the hypervisor, init system, interior permissiveness, egress posture and privilege model all emerged from questions nobody objected to. Second, a first-pass characterisation can be confidently wrong in kind rather than in detail: revision 1 of this document had the substrate, the memory and the toolchain right, and still misidentified what the environment is.