Versioned Images: Define the Environment as a Pinned Recipe, Not a Hand-Tended Machine

The agent's environment should be a versioned, declarative image, not a machine someone keeps alive. An image pins the base OS, the toolchain, and the dependency versions, so every task boots from the same known state and any past run can be re-created by booting the recorded version rather than reconstructed by hand. Shopify builds its whole stack this way: "everything. Dev environments, CI, production images: one reproducible substrate," all with Nix (Shopify case study). Anthropic's Managed Agents saw p50 time-to-first-token drop roughly 60% and p95 over 90% once sandboxes became fresh-per-task cattle reinitialized from a standard recipe.

Where sandboxing decides how strong the box is, the image decides what is inside it and that the next box is identical.

Reproducibility is first a property of how the machine is provisioned and only later an answer an auditor reads back. The auditor's change-management question is not "did someone review this?" It is "can you reconstruct the conditions under which this change was made?" On a laptop the honest answer is no: the environment is whatever that machine accumulated over two years of brew install. The image version recorded against the task is the evidence, and the boot is the proof. The compliance side of this property lives at reproducibility.

Disposable environments force the recipe to be complete

Anthropic frames this with the pets-vs-cattle analogy. Their first design put session, harness, and sandbox in one container, and that container became a pet: hand-tended, irreplaceable, nursed back to health when it hung. The fix was to make the sandbox disposable. If a container dies, the harness catches it as a tool-call error, and "a new container could be reinitialized with a standard recipe: provision({resources})" (Anthropic).

The phrase to hold onto is standard recipe. When environments are disposable, the recipe is the only durable description of the environment, and that forces the recipe to be complete. Nothing essential can live in a container that might vanish mid-task, so everything essential lives in the image and in the session log stored outside it. Together those two artifacts reconstruct any task after the fact: the image gives you the static conditions (OS, toolchain, dependencies), and the session gives you everything that happened inside them, replayable via wake(sessionId). Anthropic built this for resilience, and the TTFT drop above arrived before anyone asked a compliance question. Reproducibility is the same property, read by an auditor instead of an SRE.

The recipe is declarative: base image, toolchain, pinned dependencies

A versioned image is a declarative definition that names every layer the agent's work depends on, so two boots a year apart resolve to the same bytes. Three layers carry the load.

  • Base image. A pinned OS and system libraries, referenced by digest, not by a floating tag like :latest that resolves to a different artifact next week.
  • Toolchain. The language runtimes, build tools, and CLIs the task needs, pinned to exact versions. Stripe pre-loads exactly this into its devboxes: a fresh box arrives "checked out to a recent copy of master across all of Stripe's main repos," with Bazel and type-checking caches already warm (Stripe case study).
  • Dependencies. Application packages installed from a lockfile, not resolved fresh each boot. Resolving fresh is how a poisoned or hallucinated package enters silently, which is why install-path integrity is its own control at dependency provenance.

Shopify's substrate is the strongest published version of declaring all three at once. A River profile "is data: a system prompt, a set of skills, a set of extensions, a sandbox policy, model defaults," built with Nix so dev, CI, and production derive from one reproducible substrate rather than three drifting ones (Shopify case study). The agent's environment is the same artifact engineers and CI already run, which is the property Stripe states as a thesis: "if it's good for humans, it's good for LLMs, too" (Stripe case study).

The failure this prevents is config drift, and it is the failure teams running shared agent setups report directly. One practitioner on a shared Claude Code config: changes "happen locally with zero documentation or traceability. Nobody else benefits from the fix, I can't see what was changed or why, and a week later every team member has silently diverged" (r/ClaudeCode, community sentiment, May 2026). A declarative image is what makes that divergence impossible: the only way to change the environment is to change the recipe and roll a new version, which is a reviewable diff rather than a private brew install.

Templates are becoming a platform primitive

The pattern is standardizing below the vendor layer. The Kubernetes Agent Sandbox project (SIG Apps, announced on the Kubernetes blog in March 2026) introduces a Sandbox CRD for what it calls "isolated, stateful, singleton workloads," with three extensions that map directly onto this chapter:

PrimitiveWhat it doesWhy it matters here
SandboxTemplateA reusable definition for creating many similar sandboxesThe versioned image as a declarative API object
SandboxClaimA request for a sandbox matching a templateEvery task environment provably derives from a named template
SandboxWarmPoolA pool of pre-provisioned sandboxesRemoves the cold start, so fresh-per-task costs nothing

A template makes the tenth environment and the ten-thousandth identical by construction, because both are instantiations of the same named object. The warm pool answers the standard objection that provisioning fresh is too slow: the project cites roughly one second of pod startup overhead as enough to break an interactive agent's continuity, and pre-warming eliminates it. Stripe runs exactly this trade in production, pre-warming a pool so a devbox spins up in 10 seconds (Stripe case study). Speed is no longer a reason to reuse a stale environment across tasks; see one environment per task for why reuse was never a good trade anyway, and placement for where the warm pool actually runs.

Snapshotting makes the recipe boot fast without abandoning it

The cost of building from a recipe on every boot is build time, and a snapshot pays it once. Snapshot the environment after the toolchain and dependencies are installed and the services are healthy, then restore that captured state per task instead of rebuilding from scratch. The snapshot is the recipe, executed and frozen, which keeps reproducibility while removing the wait. Ramp's Inspect runs each session in a sandboxed Modal VM bundling its full service stack (Vite, Postgres, Redis, Temporal, RabbitMQ) and rebuilds filesystem snapshots every 30 minutes, so a fresh sandbox is at most 30 minutes out of date (Modal case study, Feb 19, 2026). Ramp's head of applied AI, Rahul Sengottuvelu, names startup time as the constraint: "We've tried to design Inspect to as close to the speed of a local agent as possible. Sandbox startup times are a huge part of that."

The 30-minute rebuild cadence is the version-control discipline made operational. The snapshot is a build artifact derived from the recipe, re-cut on a schedule so it never drifts far from the declared definition, and every task boots from a named, reproducible capture rather than a long-lived machine. A managed substrate can offer the same shape, booting a fresh VM per task from a versioned snapshot; Wallfacer (disclosure: the sponsor of this guide) is one published implementation of that approach (Wallfacer case study). Treat snapshot-based reproducibility as a fair framing to evaluate, not a finished result: Wallfacer publishes no customer-scale boot-time numbers, so its row is a design to grade rather than figures to bank.

Version the image because it will go stale

A known-good image is only known-good for a while. Anthropic's sharpest observation is that harnesses "encode assumptions about what Claude can't do," and those assumptions "go stale as models improve": context resets they built for Claude Sonnet 4.5 became "dead weight" on Claude Opus 4.5 (Anthropic). Images carry the same risk. The helper scripts, pinned tool versions, and workarounds you bake in today are assumptions about today's models and toolchains.

Versioning is what lets you hold both directions at once. Roll the image forward as models and toolchains improve, and still boot the exact version a six-month-old change was made under. The mechanism is two pins: the image version recorded in the task's audit record at provision time, and the retired image retained so the boot still works later. That pair is what converts "we use containers" into an answer to the auditor's question, and it is the operational backbone of the reproducibility property in the compliance argument.

The image version is also not the whole reproducible unit. Practitioners who treat their prompts like code report forgetting the rest: even teams that "treat prompts like code (PR, review, pipeline)... forget to lock model checkpoint and tool permission state together. Swap the model endpoint without a new PR and you've effectively changed behavior" (r/devops, community sentiment, June 2026). The image pins the toolchain and dependencies; the model version and the agent's tool permissions are the same kind of pin, recorded against the task so a replay reconstructs behavior, not just the filesystem.

The sources are silent on audits and retention

Neither primary source is writing about audits. Anthropic's article never uses the word compliance, and the Kubernetes post is an operations argument: cold starts, scale-to-zero, stable identity. Shopify's Nix substrate is a reproducibility claim about builds, with no SOC 2 or audit-policy language attached. The move from "environments are built from templates" to "the template version is evidence" is this handbook's prescription, in line with evidence as a byproduct, not a claim any of these teams make.

The field is also silent on retention: no published source states how long retired image versions should remain bootable to satisfy a look-back request. Until a framework says otherwise, the defensible default is to match your image retention to your audit-log retention, because an event log you can read but cannot re-create the conditions for is half an answer.