A cloud agent's environment is a description of how to get a working project from an empty machine. Cursor looks for it in order: first the file in the repository, then a saved personal environment, then a team one. That order is sensible: the repository is the most specific and most verifiable place, because it is visible in review and travels with the code. A personal environment stays a useful draft, but while the description lives only with its author the team has no reproducibility.
There are two preparation paths. The recommended one is to let the agent assemble the environment itself from the project's description. The advanced one is your own image through a build file. The second is needed when a project has heavy system dependencies or strict requirements for tool versions. A typical mistake there is copying the whole project into the image: the code will be fetched again at the right commit anyway, and the image is for the environment rather than for sources. The side effect of that mistake is not immediately visible - the image is rebuilt on every code change, and machine preparation turns from fast into slow.
It helps to see a complete description once. Below are a build block with an image file and a context, a command that installs dependencies and generates code, and a command that starts services. Three fields are three different roles, and they should not be confused: install prepares the disk state, start raises processes, build sets the base image. Checking that the roles are not mixed up is simple: ask of every line whether its result survives the machine being switched off.
The main requirement for the install command is idempotence. It runs when a build is created and must give the same result on a repeat run. It covers dependencies, code generation, compilation and warming caches. Long-running services do not belong here: their place is in start or in terminals, because a build preserves the state of the disk but does not preserve processes, exported variables or the contents of memory.
That distinction explains the most frequent failure of a first cloud task. A developer raises a server in the install command, the build completes successfully, and the agent then cannot reach the service - the process did not survive the boundary between stages. The symptom looks mysterious, the cause is simple: the disk is preserved, what is running is not. The same rule explains the second most common puzzle - a variable exported during install and gone by the time the agent works.
An environment can clone several related repositories at once, and that opens the way to coordinated changes across project boundaries. But the group is kept minimal deliberately: every extra repository widens the context, adds credentials and increases the blast radius of a mistake. Three repositories in a group are three sources of untrusted content, not only three sources of code.
The disk rule leads to a practical technique that pays off fastest. Everything that can be done once and left on disk is moved into install: dependencies, generated code, compiled artifacts, warmed caches of the bundler and the test runner. Every such minute is saved not once but on every agent run on top of that build, and one build serves many runs. The reverse is also true: a heavy install rebuilt on every change to the description eats the gain, so rarely changing system parts are kept in the image and frequently changing ones in install.
Such a description has a limit that people trip over on the first attempt to connect an external service. Idempotence is guaranteed only for what you control: a command that pulls packages without pinned versions or reaches a third-party address is reproducible exactly until the outside world changes. The sign that catches this in real work is a build failing with no change in the repository at all, or, worse, building successfully but producing different behavior. It is cured not by debugging the agent but by pinning versions and moving external dependencies into the image, where they become a deliberately updated layer.
The engineering conclusion is simple: a cloud environment is infrastructure code and must be treated as code. It is versioned together with the project, reviewed, checked for reproducibility and must be able to build from scratch. An environment that builds only on the third attempt and only for its author is unfit for autonomous work regardless of the model's quality.
The typical failures are predictable. Starting a long-running service in the install command and losing it. Copying the whole project into the image instead of the environment. Making install non-idempotent and getting different builds from one description. Leaving external dependencies unpinned. And putting more repositories into one group than the task needs.
// .cursor/environment.json
{
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"install": "pnpm install && pnpm run codegen",
"start": "pnpm run dev"
}
// install is idempotent; long-running services belong to start, not to install