You prevent drift at two points. Before the agent writes, give it the system that actually exists in your code: the tokens, the components and the rules, not an aspirational document. After it writes, check the change against that system: raw values that equal a token, near-misses, duplicated components, one-off overrides. Prompts alone do not hold; a check you can run does.
Why AI-generated UI drifts
Agents optimise for code that works and looks right in isolation. A hex value that renders the right purple passes every visual check, so nothing stops it. Over many changes those values accumulate: in the Lunary scan, 22 hard-coded colours exactly equal a declared token and are written 436 times in total, and 78 more sit perceptually close to one.
Before: give the agent the real system
Documentation that describes the system you intended is less useful than a description of the one you have. Reconstruct it from code: which tokens are declared, in which themes and modes, which are used and which are dead, which components exist and which names collide.
Keep the hand-over short and specific. A list of tokens with their roles, a list of components with their purpose, and a few rules (never write a raw colour when a token exists) are more effective than long prose.
After: check the change
Run the same analysis on the code after the agent has written it. Exact drift is deterministic: a raw value that is string-identical to a token is a finding with no judgement involved, so it can be fixed or rejected in review. Near-matches are inferences and should be reviewed by a person.
saer scan .
# open .saer/report.htmlWhat Saer does about this
- Colour drift detection in the beta: exact drift, near-matches with their distance, dead and conflicting declarations.
- Typography and foundation drift (spacing, radius, shadows, z-index, breakpoints, borders, opacity, motion): in the beta.
- Component duplicates and overrides: in the beta.
- A self-check an agent calls through MCP,
saer_check_changes, which judges only the lines it wrote: in the beta.
- CI Guard, a pull request check that fails on new drift: planned.
Every capability and its state: what Saer checks.
See it on your own codebase.
Request early access