
Each new feature works alone and connects to nothing. Six architectural moves that give the rooms you have already built a blueprint to obey.
Sarah Winchester spent 38 years adding rooms onto rooms with no master plan and no deadline. Carpenters worked in shifts, and the building never stopped.

When the 1906 San Francisco earthquake wrecked part of the house, she sealed off the damaged floors and kept building elsewhere. What stands today has staircases that climb into ceilings and doors that open onto walls.
Reads like enterprise software already.
Most apps produced through AI prototyping are being built the same way. Each addition is cheap now. A copilot on one screen, a summarizer on another, a “draft this” button somewhere else, a data model that makes no sense, each spun up in an afternoon.
Every feature works alone.
Step back and you have a house nobody can find their way through.
The field is already there. Nearly nine in ten organizations now use AI, yet most still haven’t rewired their workflows around it. That gap is the whole problem stated as a statistic.
The features arrived faster than any structure to hold them, so each one shipped carrying its own vocabulary, its own output shapes, and its own private opinion about what should happen when something breaks.
It’s an information architecture problem, and architecture is something your team already knows how to build.



In 2008 I reposted a letter on my blog, If Architects Had To Work Like Web Designers, that had been circulating for years with no author anyone could name but still deserves a lot of credit. A client writes to an architect asking for a house with somewhere between two and forty-five bedrooms, drawn so the bedrooms can be added or deleted easily. He wants a complete set of blueprints before any real design work, and the house under roof within 48 hours of approval.
It was funny because it was impossible.
It isn’t impossible now.
Prototyping made every one of those requests cheap to satisfy, and what disappeared along with the cost was the friction that used to force somebody to draw a plan first.
What follows is a retrofit, not a rebuild. Six moves on the app you have already shipped, and you can apply them on the apps you build today with a bit of care.

Anchor the Scaffolding and Harnesses First
Before you build a single feature, define the object model. Not the database schema, the shared one: the real nouns your product works in, and the verbs scoped to each.
A project can be archived, a document can be shared, and an invoice can be approved and paid but never archived, because your business doesn’t work that way. Those constraints are the useful part, and they only exist if somebody writes them down.
This is the scaffolding everything else is built against, and the harness the other five moves hang from. When a feature offers to “create a follow-up,” that request has to land on something real, with a shape and a place to live.
If “follow-up” isn’t an object anyone defined, you’ve just let that feature conjure a room that exists on no floor.
Those constraints are the useful part, and they only exist if somebody writes them down.
Naming is most of the work, and it’s rarely as settled inside a team as everyone assumes. UX Components compares how design systems name the same things differently, which is a useful mirror to hold up to your own vocabulary.
A shared object model tells every feature what exists, what can be done to it, and what can’t, so the work gets built inside your world instead of a parallel one.
Action Items
- Write the noun list before the feature list. Enumerate the real objects and the verbs scoped to each one, and treat anything a feature wants to do that isn’t on the list as a gap to close rather than a thing to fake.
- Check every action against a real object. For every “this feature can create, update, or delete X,” confirm X has a defined shape and a persisted home. If it doesn’t, the affordance is conjuring.
- Publish a semantic contract. One page, objects and verbs and relationships, signed off by engineering and design together so both sides are building against the same world.

Compose From Defined Patterns and Components First
Above the individual output sits a small library of interaction patterns that govern how a feature behaves over time. Suggest, draft, summarize, classify, plan and confirm. Each one is a named behavior with defined states running from entry through in progress, result, recovery, and dismiss.
Most teams have 40 features and zero patterns, so every engineer and designer decides on the spot what happens when something fails, and forty people making that call separately produce forty different answers. Failure isn’t an edge case here. Design the failure once, at the pattern level, and every feature inherits it.
That library should govern what a feature shows as strictly as it governs how the feature behaves, and this isn’t a foreign discipline you’re importing.
Developers build controlled languages constantly and so have designers, most of the time not well.
An enumeration that permits four values and rejects the fifth is one. An interface contract that throws on any payload off its schema is one. Engineers already narrow what their code is allowed to say, because the alternative is a system where every caller guesses and every integration eventually breaks in a way nobody can trace.
One controlled language, spoken everywhere, and no bespoke surfaces invented per feature.
A design system is that same move aimed at output instead of internals, a deliberately narrowed vocabulary, the way Simplified Technical English keeps aircraft manuals unambiguous. A feature doesn’t get to render free-floating prose blobs.

I have a whole catalog of them here at UX Components.
It returns structured payloads that resolve to components you already own. One controlled language, spoken everywhere, and no bespoke surfaces invented per feature.
Action Items
- Name your interaction patterns. Reverse-engineer what you already ship into five or six named behaviors, then document the states each one owns from entry through recovery.
- Compose new work from the library. Build the next feature by assembling existing patterns and components, and when it needs one that doesn’t exist, add it deliberately rather than improvising it in place.
- Unify recovery across features. Design the error, empty, low-confidence, and timeout states once at the pattern level so all forty surfaces inherit the same behavior, and refactor all the time.
- Allowlist the output components, then gate additions. Define the closed set that feature output can resolve to, cards, differences, tables, timeline rows, form prefills, and make any proposed bespoke surface justify why nothing in the set can carry it.
- Return payloads, not prose. Rewrite free-text outputs as structured data the front end renders through existing components, with the schema derived from the component properties you already have.

Keep a Running Information Architecture
The information architecture most teams have is a launch artifact. Somebody drew it before the first release, pasted it into a deck, and never opened the file again.
Forty features have landed since then. The map didn’t move once.
That matters more than it sounds, because every move that follows depends on being able to see the current shape of the product. You can’t reconcile drift you have no picture of, and you can’t scope a feature to a level you never drew.
A map that only existed before the first release describes a building nobody lives in anymore. It has to be a living document.
A running information architecture is a working document for both humans and agents rather than a deliverable: routes, levels, what lives where, and which objects surface at each one, updated when features ship instead of when somebody asks for it.
I’ve argued before that site maps are a lost art and I haven’t changed my mind. They give you the bird’s-eye view of a product that nobody has when features arrive one screen at a time.
Action Items
- Redraw the map when features ship. Put updating the information architecture in the definition of done, so the document moves at the same speed as the product rather than lagging a year behind it.
- Generate the map from the routes. Read the current structure back out of the router and navigation code, then reconcile it against the drawn version, because the code is what users are walking through today.
- Give every level an owner. Name who decides what belongs at each level, or new features will keep landing wherever the first available screen happened to be.

Refactor on a Standing Cadence
When the 1906 earthquake wrecked part of her house, Sarah Winchester didn’t repair it. She sealed off the damaged floors and kept building somewhere else.
That instinct is alive in every team that ships a replacement feature and leaves the old one running behind a flag nobody revisits.
The three moves above are a snapshot, and snapshots decay.
- New objects show up that the semantic contract never named.
- A deadline lands and somebody bypasses the pattern library just this once.
- A component gets forked because the original didn’t quite fit, and now there are two of them with different behavior.
None of that is negligence. It’s what accumulation looks like when nobody has scheduled the time to reconcile it.
Sealing off the damaged wing is cheaper than fixing it, right until the day you need that part of the house.
Sealing off the damaged wing is cheaper than fixing it, right until the day you need that part of the house. So the reconciliation can’t be the thing you get to after the roadmap, because you never get to it. It goes on the roadmap, sized and scheduled like any other work, and the architecture stays true only for as long as you keep paying that bill.
Action Items
- Schedule the reconciliation rather than hoping for it. Book a standing block each cycle to fold new objects into the contract, retire forked components, and bring bypassed features back onto the patterns.
- Delete the sealed-off wings. Every replaced feature still running behind a flag is a room with no door, so set a removal date when you ship the replacement instead of deciding later.
- Re-derive the contract from what shipped. Read the object model back out of the code each quarter and compare it to the document you published, because the gap between them is your actual drift.

Bind Feature Scope to Location
Stop treating AI as a capability that floats over the whole app. Each feature is contextual. What it can see, suggest, and do should inherit from where the user is standing in the information architecture. At the project level, project verbs. Inside a document, document verbs. Move, and the affordances move with you.
This kills the worst pattern in these builds, the omniscient box that can do anything and therefore advertises nothing. A global “ask anything” field looks generous on the design review screen and behaves like a séance once it ships. Users type, guess, and give up, because nothing about the interface tells them what’s on the other side.
Location carries the intent, and the complexity you refuse to absorb gets handed to the user.
Complexity doesn’t disappear when you skip this step, it simply moves somewhere less convenient. Location carries the intent, and the complexity you refuse to absorb gets handed to the user. That person now has to hold a model of your entire system in their head to write a single request, which is a tax you declined to pay and passed along quietly.
Action Items
- Map scope to location. Write a scope table pairing each level of your information architecture with the verbs available there, instead of leaving it as tribal knowledge in three people’s heads.
- Replace the global box with entry points. Put a scoped affordance at each level that can only do what belongs to that context, so the interface advertises its own capabilities.
- Test the mental model. On every screen, check that a user can finish the sentence “I’m here, so this can ___.” If they can’t, the scope isn’t legible yet.
- Name what the feature can’t do. Scoping only pays off if the limits are visible, so state them where the user is standing rather than letting them be discovered through a failed request.

Promote Traceability to a Surface
The last move is the one teams defer and then retrofit under pressure, usually the week before a compliance review. Where did this come from, how confident is the feature in it, and what is it working from? That should be a reusable pattern in the design system, not a footnote someone adds when legal asks.
The need here is measurable.
When Columbia’s Tow Center tested eight generative search tools against quotes from real articles, the tools returned incorrect answers to more than 60% of queries, and the premium ones were the most confident while being wrong. Confidence doesn’t arrive calibrated, so the interface has to carry the doubt the model won’t.
Build it once and every output inherits it the way it inherits your typography.
A source affordance the user can open, a confidence treatment, a “show your work” panel, a state for stale data. These are components with defined behavior, not copy written per feature.
It disciplines the build as much as it reassures the user.
It disciplines the build as much as it reassures the user. When every output has to carry its source, the system forces the work to ground its claims instead of free-associating.
Action Items
- Build the traceability kit. Design the source link, confidence treatment, show-your-work panel, and stale-data state as inheritable parts, then retrofit your highest-exposure outputs first.
- Trace every asserted claim. Require any output that asserts something to carry a path back to a source the user can open, and treat an output that can’t show its work as a defect.
- Design the low-confidence state first. Before the happy path, decide what the interface shows when the feature isn’t sure, what the user can do about it, and how that output is visually distinguished.

The Architecture You Draw First
Step back and the harness has a shape. The semantic layer is the spine, the pattern and component library handles composition, and the running information architecture is the map. Refactoring is the maintenance that keeps it true, scope binds each feature to a place, and traceability is the connective tissue.
None of these is exotic.
They’re the moves good product teams have always made, and cheap prototyping raises the cost of skipping them.
None of this structure is really for your users. They never see the object model or the scope table. It’s for the machine.
A model that can only resolve against defined objects, act within a scoped location, behave through named patterns, render into known components, and cite its sources is a tenant inside an architecture it can’t escape. That’s the whole trick. You’re not making the model smarter. You’re giving it a smaller, better-drawn house.
That 2008 letter ends with a postscript wondering whether what he needs is not a house at all, but a travel trailer. It’s still the right question to ask before you add another room. Winchester had unlimited money and 38 uninterrupted years and never got a building. Draw the blueprint, then let the features move in.
Don’t let AI build a Winchester Mystery House was originally published in UX Collective on Medium, where people are continuing the conversation by highlighting and responding to this story.