Skip to content
NO FEED

Understand the changes. Choose the tools. Put AI to work.

← Articles

NO FEED · AI-assisted development

Build a reproducible development environment for your coding agent

Build a coding-agent environment with a declared toolchain, locked dependencies, repeatable bootstrap and a real readiness check. Start from a clean checkout.

Consider a hypothetical image-processing service. An agent changes a Python function correctly, but the test needs a native image library installed only on the maintainer's laptop. The agent spends its session searching for an alternative implementation. The task has quietly changed from fixing application behavior to reconstructing a missing machine.

Before asking an agent to repair a failing test, make sure a fresh environment can run that test. A reproducible agent environment needs a declared toolchain, a repeatable bootstrap and an observable readiness check. A container configuration helps describe those pieces; its existence does not prove that they work together.

Start with one agent and one disposable environment. Parallel instances introduce separate state-ownership problems, covered in our worktree and application-state guide[1]. The problem here is whether a single clean instance can reach the first meaningful check.

Give each setup layer a job

A dev container can use an image, a Dockerfile or a Compose configuration. The development-container specification separates those choices from lifecycle commands and environment variables. [2] Keep that separation visible in the repository instead of burying every setup operation inside one shell line.

Layer Put here Proposed acceptance evidence
Base environment OS, language runtime, native tools The built environment reports the intended versions
Project dependencies Lockfile and package-manager configuration A clean install succeeds without rewriting the dependency declaration
Bootstrap Repository-specific generation and setup The command exits successfully and can be rerun deliberately
Runtime services Test database, application process, fixtures A functional readiness check reaches the intended disposable service
Agent instructions Where to start and how to verify The agent identifies the actual setup and test commands

This table is a proposed repository design, not a universal container recipe. The image service needs its native library in the base environment and test fixtures in repository setup. Another project may have no services at all. Avoid adding a database or orchestration layer just because a template includes one.

Pin what you intend to reproduce

Docker image tags can move. Docker recommends digest pinning when the same image version matters, while noting that a pinned image will not silently pick up later security fixes. [3] Record who updates that pin and how the update is checked; immutability and maintenance are separate responsibilities.

A dependency lockfile has a narrower role. For an npm-based project, npm ci requires a lockfile, fails when it conflicts with the package manifest, removes an existing dependency directory and does not rewrite the manifest or lock. npm also warns that installation flags affecting the dependency tree must match those used to create the lockfile. [4]

Do not translate that behavior into a guarantee of identical environments. Your native compiler, package-manager version, operating system and test data still need declarations. In the hypothetical image service, freezing Python packages does not install the missing native library. The useful target is an explainable set of inputs, not a claim that one file captures an entire machine.

Keep the intended language and package-manager versions next to the bootstrap instructions. If an environment refresh changes them, review that as a setup change rather than letting the agent discover the difference while working on an unrelated bug.

Make readiness explicit

The development-container lifecycle contains a subtle trap. The specification permits postCreateCommand to continue in the background after successful environment creation is reported; waitFor controls the stage that must finish before proceeding. Its default is updateContentCommand. [2]

If the test dependencies are installed during post-create, the agent needs to wait for that step. Otherwise, an early “module not found” may mean setup is still running. Our proposed check is to start the agent through the real launcher, record bootstrap completion, then run a small project-owned verification command. A green container status is not a substitute for that result.

VS Code's dev-container guide distinguishes tools baked into a Dockerfile from commands that need the mounted workspace. It also says post-create commands must exit; a permanently running application server does not belong in that blocking setup step. [5]

For the image service, bootstrap can install project dependencies and prepare sample inputs. A separate start command launches the application. A readiness check then sends a harmless sample image and checks the expected response. Label a setup failure as setup failure; do not encourage the agent to rewrite working application code until the environment is ready.

Rebuild before trusting a warm environment

NO FEED proposes a clean-room rehearsal with disposable resources. Take a fresh checkout at a named revision, create the declared environment, run bootstrap, and execute one meaningful test. Keep the commands, versions and failure output. Never use deletion of a developer's working directory as a shortcut for this exercise.

Repeat bootstrap once in the prepared instance if rerunning it is part of the supported workflow. It should either complete predictably or explain which prior state prevents it. A command that succeeds only because an earlier manual repair left a file behind has not demonstrated the documented path.

Then rebuild a second disposable instance. Check whether the same test runs without copying hidden files from the first. This is especially useful for generators, downloaded browser binaries and native dependencies: list them as declared preparation rather than relying on a previous session's leftovers. We have not run this rehearsal on a sample repository for this article.

Separate reproducibility from isolation

A 14 October account by u/reminiscent-fruitbat describes a macOS container setup where the startup path mattered: using a runtime start button bypassed its firewall startup script. The author later changed the design:

“I’ve since dropped SSH and moved egress to a separate proxy container.”

— u/reminiscent-fruitbat, 14 October 2026. [6] [7]

This is an attributed setup report, not a security audit. Its later revision supersedes the initial SSH design and makes the launcher part of the configuration worth preserving.

A dev container may still have access to important host files. Docker bind mounts are writable by default, and a process inside the container can change the mounted host content. A read-only mount changes that specific access. [8]

Review mounts, credentials and network destinations independently from the build recipe. Our proposed default is to expose the project and the minimum approved test access, with secret values supplied through the environment's supported secret mechanism. Document required access names without committing their values. A reproducible setup that consistently exposes unnecessary credentials has reproduced the wrong condition.

Choose one existing test that a new contributor should be able to run. Make a clean, disposable agent environment reach it using only the checked-in setup and explicitly supplied access. Fix the first undocumented prerequisite before giving the agent a larger coding task.

Sources & context

  1. worktree and application-state guideRead 19 October 2026.
  2. Development Containers specificationConfiguration, lifecycle and waitFor; read 19 October 2026.
  3. Docker: Building best practicesImage digest pinning and maintenance tradeoff; read 19 October 2026.
  4. npm v11: npm ciVersioned clean-install behavior; read 19 October 2026.
  5. VS Code: Create a Dev ContainerBuild versus workspace setup and lifecycle commands; read 19 October 2026.
  6. u/reminiscent-fruitbat: macOS container setup14 October 2026; startup behavior self-reported, initial design later revised. Original and replies checked 19 October.
  7. Author's revision: SSH removed, separate egress proxyLater reply on 14 October 2026; no independent security validation. Checked 19 October.
  8. Docker: Bind mountsHost write access and read-only option; read 19 October 2026.
YOU’RE DONE. CLOSE THE TAB.

The useful part, in your inbox.

One complete edition every weekday, with practical takeaways.