You ask the agent to add a settings page. It comes back with something that renders, and two things are wrong. The primary button uses the accent colour your design system reserves for a single call to action. The form calls an option that the form library dropped one major release ago. You explain both in chat, it apologises, it fixes them. Next session, in a different file, it does both again. It is tempting to read this as carelessness. It isn’t. Nobody ever told it — not in any form it could read while it was working.

No pilot learns the circuit by landing wrong

Before flying into a small airfield you read its published page. Which way the circuit turns. The radio frequency. The height to hold over the village. Whether the grass strip is closed this month. None of it is hard, and none of it is deducible: these are local decisions somebody made once and wrote down. A pilot who skipped the page would recover the same facts by trial, one irritated radio call at a time, and would arrive having learned nothing that carries to the next field.

An environment contract is that page, handed to the agent at run time. It is the explicit declaration of the rules of the place the agent has to work in — what is allowed, what is forbidden, which formats are expected. It gets built the unglamorous way. Watch where a fixed model keeps failing in a deterministic environment. Distil those failures into explicit rules: preconditions, expected action formats, operating limits. Inject them into the context of every run. The environment itself is untouched. What changes is what the agent knows about it before it acts.

The concrete version is small enough to be disappointing. In an operating-system environment, an agent can fail again and again because it does not know a command needs an explicit working directory before it runs a file. Stated once as a constraint, that failure stops repeating in every run after, not only the one where you caught it. Nothing about the model changed. What looked like weak reasoning was a mismatch of interface: the agent reasoned fine about a place whose rules it had been left to guess.

A value written with its reason survives contact

The same move works on taste, which is where agents look most confused. A design document written for agents carries two things in one file: structured values in the front matter — colours, spacing, type — and prose underneath that explains intent. The token gives the exact colour of your call-to-action buttons. The prose says it must stay the only interactive accent on the page. The agent now has a value it cannot misread and a boundary it cannot invent its way around. Ship only the tokens and the intent is lost, applied correctly in the wrong place. Ship only the prose and it guesses the values.

Once the rules are written, they can be checked before anything is built from them. A linter reads the specification, verifies token references and structure, finds duplicated sections, and computes signals like contrast ratio. It returns findings with a severity and the path of the component. Button text without enough contrast on its background comes back named, with the measured ratio attached, and the token gets changed before the page exists. That is the decision this really touches: how much you are willing to let run unattended. A check that runs by itself is cheaper than a review that has to be scheduled. It is not a verdict on the design — it confirms the constraints you declared, nothing more.

The right page beats the one it remembers

Charts expire. Every model carries a remembered version of every library, frozen whenever its training stopped, and it will reach for that memory with total confidence. The fix is unromantic: ask by stable library identifier and, where you have it, by version, so what comes back is the v3 page rather than a plausible v2 snippet that someone posted years ago. Searching by name and accepting the first credible example is how obsolete APIs get into your code wearing a straight face.

Four moves, one shape. A rule distilled from real failures, a value with its reason beside it, a check that runs before the work, a page pinned to the version you actually depend on. Each is a decision already made, written where the agent reads, and kept current. That is worth more than any explanation repeated in chat, because chat scrolls away and the file does not. Context is not only what you fetched, it is what the system knows before it starts. Write the environment down, or the agent will keep making it up.