← Omkar Khadamkar

AI drift, the field notes

AI-generated UI gets ~90% right. These are field notes on the 10% — and what 45,000 impressions, 60 comments, and practitioner calls taught me about killing it.

REV 02 DATE 2026-07 FIVE CHAPTERS · EVERY INSIGHT ENDS IN SOMETHING YOU CAN TRY TODAY

The missing 10% is never layout. It is precision. Four classes of drift, each one invisible at a glance.

MEASURED PER COMPONENT · PER REGENERATION · SCORED BY DIFFING OUTPUT AGAINST THE LIBRARY

DRIFT CLASS 1 OF 4VALUE DRIFT

The number changes.

A control spec'd at 60px renders at 48px. Plausible, proportional, wrong — 48 is a believable height, which is exactly why nobody catches it.

Submit
SPEC · 60px
Submit
RENDER · 48px
TRY THIS

Bind every dimension to a named token the AI can point at — never a number it has to retype.

DRIFT CLASS 2 OF 4ATTRIBUTE DRIFT

The detail thins.

A 3px stroke returns as 2px. The component is right, the geometry is almost right — and almost compounds across every surface that inherits it.

Active tab
SPEC · 3px
Active tab
RENDER · 2px
TRY THIS

Give hairline values their own tokens. Thin details drift first, because a 1px miss looks like rendering, not error.

DRIFT CLASS 3 OF 4STYLE SUBSTITUTION

The treatment swaps.

A tint fill quietly becomes a solid. Same hue family, different treatment — a reviewer approves it at speed, an audit rejects it on sight.

SPEC · TINT
RENDER · SOLID
TRY THIS

Name the treatment per state in the spec — "tint", not "light red". Adjectives are where treatments swap.

DRIFT CLASS 4 OF 4HALLUCINATED VALUES

The gap gets filled.

A missing cell in a color table gets a confidently invented swatch. To a generative model, absence reads as permission.

SPEC · GAP DECLARED
?
RENDER · INVENTED
TRY THIS

Render every empty cell as an explicit "—". A declared gap is an instruction; a blank is an invitation.

Better prompts did not fix it. Documentation a machine cannot misread did.

TWO FINDINGS WITH TEETH

FIX 1 OF 2RULE FRAMING

Prohibitions decay. Directives hold.

"Never do X" degrades at generation time. The same rule as a positive directive with the exact value holds. Published research agrees: models get measurably worse at negated instructions as they scale.

Never hardcode the badge height
DECAYS
badge height: var(--badge-h) = 24px, always
HOLDS
ECHOED INDEPENDENTLY IN THE THREAD: JED SANFORD · MARIUSZ C.
TRY THIS

Rewrite one "never" rule in your docs as a positive directive with its exact value. Then regenerate and watch which version survives.

FIX 2 OF 2VALUE BINDING

Named values beat typed numbers.

If the AI retypes "48" from memory, it can misremember. If it points at one named token, there is nothing to misremember. The discipline tokens always promised, now load-bearing.

retype"48"?"44"?
MEMORY · CAN MISREMEMBER
point--control-h60px
REFERENCE · NOTHING TO MISREMEMBER
CREDIT: SVETLANA HOLSTON — MY GUIDELINES WERE REWORKED BECAUSE OF THIS COMMENT
TRY THIS

Audit one component spec for retyped numbers. Replace each with its token name. Count what you find — the count is your risk surface.

The verification taught me more than the finding did. Five rules for testing without fooling yourself.

WHERE MOST OF MY REGENERATION BUDGET WENT

RULE 1 OF 5DON'T LEAD THE WITNESS

Never name the fix in a regeneration prompt.

Prompts name pages and point at the system — never the correction. If the fix lands unprompted, your documentation captured it and activated it. Name it, and you have tested your prompt, not your system.

"make the button 60px tall"
TESTS YOUR PROMPT
"rebuild the page from the current spec"
TESTS YOUR SYSTEM
TRY THIS

Regenerate one page from a generic "match the spec" prompt. Count what lands unprompted — that count is your documentation's real score.

RULE 2 OF 5TRIAGE

Every miss has one of two causes.

They need different repairs — diagnose before you fix, or you fix the wrong layer.

A MISS. DID THE MODEL TOUCH IT?
NO → RULE NEVER FIRED
ACTIVATION FAILED
STRENGTHEN THE TRIGGER
YES → STILL WRONG
CAPTURE FAILED
FILL THE SPEC GAP
TRY THIS

Label every miss in your next review "untouched" or "touched". Untouched: make the rule fire. Touched: fix the spec.

RULE 3 OF 5THE DELETION GAP

Addition is cheap. Deletion needs an explicit instruction.

In revision passes, models happily add what the spec defines but rarely remove what it does not. Stale UI survives every update unless subtraction is itself a positive directive.

ABC ← NOT IN SPEC
AFTER REVISION · C SURVIVES
AB+ "REMOVE WHAT THE SPEC DOES NOT DEFINE"
C IS GONE
TRY THIS

Add one line to every revision prompt: "remove whatever the spec does not define." Watch what disappears.

RULE 4 OF 5CHECKSUM TRIPWIRE

One control's width doubles as a checksum.

A single pixel off means the token chain broke somewhere upstream — long before a human eye would catch it.

69px ✓ CHAIN HELD
70px ✗ CHAIN BROKE
TRY THIS

Plant one odd-valued dimension as your tripwire. Check it first on every regeneration — it audits the whole chain in one glance.

RULE 5 OF 5ORDER OF REVIEW

Verify foundations first.

Color and token errors ripple into every downstream component. Settle upstream truth before judging components, or you will re-review everything twice.

1 · TOKENS & COLOR
2 · FOUNDATIONS
3 · COMPONENTS
4 · PAGES
TRY THIS

Re-order your next review bottom-up. If the color page is wrong, stop — nothing above it is worth judging yet.

Nobody disagrees drift exists. Teams disagree on where to kill it. Six enforcement points along one pipeline — tap each to see whether it fits your stack.

BUILT FROM 60 PUBLIC COMMENTS AND PRACTITIONER CALLS · EVERYONE CREDITED

DESIGN
SYSTEM
DOCS &
TOKENS
GENERATION
OUTPUT
PRODUCTION

A · Make the documentation machine-readable.

Acts at the docs & tokens stage. A guideline per component, positive directives, exact values, and a stylesheet generated from the production token file — one token truth. Verification is a library diff on every regeneration.

FITS IFYou cannot touch the repo. This is the point that works when everything downstream is fenced.
PRACTITIONER: THIS IS MY SETUP

B · The agent places the real component.

Acts at the generation stage. Drift dies at the source: the agent uses the actual coded component instead of re-creating it. "It IS the actual design system component."

FITS IFYou live in the repo, and your components are coded, current, and importable.
MATÍAS MARTÍNEZ BOYLSTON · AKSHAY KHURANA · ANGEL J. SÁNCHEZ

C · Point, don't describe.

Acts at the docs → generation seam. Tell the agent where to look — tokens in JSON, YAML, CSS, plus a usage spec — instead of rebuilding components from prose. Rebuild-from-description varies run to run no matter how stringent the text.

FITS IFYour sources are pointable: structured token files exist, even if the production code is off-limits.
JIMMY LEONARDSSON · NICK ANDREWS

D · A reviewer agent audits the generator.

Acts at the output stage. Generator agent plus a separate reviewer/validator agent — a common pattern in practice, and common is not a demotion: it is the most portable point on the map, because it asks nothing of your stack. A manual diff loop is the human-powered version.

FITS IFAnything. Start here if you can start nowhere else.
SVETLANA HOLSTON (WHO RIGHTLY CALLS IT COMMON) · MAYANK AGARWAL

E · AI edits the description. A machine builds the code.

Replaces the generation stage. What I would call a deterministic materializer: the AI works on a description of the system, and a deterministic factory generates the code — generation variance disappears entirely.

FITS IFYou can adopt a factory toolchain, or build one. Watch this space; it is where the vendors are heading.
ARCHITECTURE: ANDREI HERASIMCHUK'S SELDON · ADJACENT: REWEAVER, DEMBRANDT

F · Replace the token layer itself.

Acts at the design system root. Audit the production system, swap in an AI-legible token layer, confirm compatibility, ship. Authority is won by evidence, not negotiation: read-only access, a staging proof, dark mode as the diagnostic, then the CTO.

FITS IFToken authority is held — or winnable. Run in greenfield and legacy both.
SVETLANA HOLSTON · REDICA, METRC
THE META-PATTERNNO UNIVERSAL GUARDRAIL

Each stack and each generation point needs its own enforcement point, or a combination. The question is never "how do I stop drift" — it is "which enforcement points can my stack actually support."

CREDIT: MAURÍCIO JUBA
TRY THIS

Mark the two points your stack can support today. Run them in combination — one upstream, one downstream.

Two questions still open. This is where the notes grow next.

CORRECTED IN PUBLIC, TWICE — AND BETTER FOR IT

OPEN PROBLEMUNSOLVED

If the docs regenerate themselves, what stays true?

Self-supporting documentation loops: docs that produce their own next source. If output becomes input, drift compounds quietly — unless something outside the loop stays truth. My anchor today: the library, plus a diff on every regeneration.

DOCS
GENERATE
RE-INGEST
ANCHOR: THE LIBRARY
PROVOCATION: VARYA STEPANOVA · ANSWER: NOBODY HAS ONE YET
TRY THIS

If your docs feed their own regeneration, name your outside anchor now. No anchor, no truth — only momentum.

THE BOUNDARYSPLIT TRUTH

Split authority is not the problem. Split truth is.

The real boundary is not legacy vs greenfield — it is how token authority is held. Where it is shared, fidelity lives in the contract: one canonical, executable token layer — design owning semantic intent, engineering owning production integrity.

DESIGNSEMANTIC INTENT
ENGINEERINGPRODUCTION INTEGRITY
ONE CANONICAL, EXECUTABLE TOKEN LAYER
CONTRACT PHRASING: SVETLANA HOLSTON
TRY THIS

Write down, today, who owns semantic intent and who owns production integrity for your tokens. If two systems hold truth, drift already lives between them.

Is your enforcement point on this map?

If your team kills drift at a point not shown here — or you have watched one of these six fail — I want to hear about it. The notes grow as the conversations do.

FIELD NOTES v2 · OMKAR KHADAMKAR · DESIGN SYSTEMS × AI-NATIVE DOCUMENTATION
SOURCED FROM PUBLIC THREAD COMMENTS AND PRACTITIONER CALLS · EVERYONE CREDITED BY NAME · METHOD OVER INTERNALS THROUGHOUT
OMKARPKH@GMAIL.COM · OMKARUX.COM