Most software asks you to configure it. You arrive, you are handed a settings screen, and the burden of describing how you work falls on you - before you have used the thing enough to know.
The alternative is software that watches how it gets used and quietly rearranges itself, and stays in the periphery while it does1 - not a model in the cloud, usually a table and a sort.
There were ten of these. Six are left, and the cut is the useful part: what survived is the set where the mechanism has either been measured in a study or run at scale in a shipped product, so the constants below are somebody else’s rather than mine. Firefox’s address bar supplies the decay rates. Gmail supplies the confidence weights. A CHI paper from 2009 supplies the onset timing, and an IUI paper from 2010 supplies the clamp that keeps a hit target from running away from its key. What went were four components resting on mechanisms I could argue for but not point at - a Markov toolbar, a rhythm-aware autosave, a co-occurrence tagger, a disclosure counter.
The rule that survived the cut: no two may share a mechanism. It is easy to build six adaptive components that are all “count the uses, sort descending” and learn nothing from the set, so counting appears exactly once - and even there it is bounded, and it forgets. The rest watch interruption cost, correction, velocity, onset, and the gap between where a finger aims and where it lands. Every one is running on this page. Nothing here is a screenshot.
Each keeps its state for the length of your visit only. Nothing is stored, nothing is sent anywhere.
Command palette
Frecency
Promotes what you have been using into a small zone of its own, and lets it cool off again when you stop. The list underneath never moves.
⌘K
Use one twice and it rises into the zone at the top. Leave it alone and it cools back out. The list underneath never moves.
Two tiers, after Firefox, which runs a small learned layer above a stable ranked base rather than sorting one list. A pick updates only that command - the source documentation gives the update as use_count × .9 + 1, which approaches ten and stops, because a command you use fifty times a day should not become permanently unassailable. Decay runs on a clock rather than on use, since decaying per-use freezes the model of anyone who walks away: ×0.975 per idle tick, and anything under 0.975^90 is dropped, which in Firefox means ninety days unused. The promoted zone holds two, and it holds copies: moving a command up there would close the gap it left and shift everything below it, which is the exact cost the arrangement exists to avoid. The list underneath is in its authored order and stays there permanently.234
Quiet notification
Interruption cost
Times how fast you dismiss it, reads that as the cost of having interrupted you, and demotes itself a step - down to a floor it cannot cross.
Dismiss it fast and it comes back smaller. It demotes to quiet, never to silent.
Time-to-dismiss as a proxy for value. Under two seconds reads as an interruption rather than information, and the next notification is demoted a step - banner, then corner toast, then a dot. The floor is the entire point. Apple's attention-aware features quiet an alarm you look at without dismissing, and keep it quiet next time, and people have overslept because of it: a system that can learn its way to never telling you anything has a bug, not a feature. So the floor is a constant with an invariant on it that dismisses a thousand notifications and checks it is still saying something. The pin is the other half. Findlater and McGrenere put static, adaptive and adaptable menus in front of twenty-seven people and the adaptable one won on preference despite losing on speed - control has value independent of performance, which is Horvitz's point too: automation never removes the manual path.567
Learned defaults
Correction
Weighs your overrides against the factory setting rather than counting them, so the strongest signal a user gives is priced like one.
Export quality
Change it, hit “New document”, change it again. It weighs your corrections against the factory setting - which starts ahead.
Gmail's Priority Inbox, scaled down to one setting. The obvious version counts corrections and flips at two, but two is a designer's guess wearing a principle's clothes. Priority Inbox instead attaches a confidence weight to every training example and weighs an explicit correction above a passively observed signal, combines a global model with a per-user delta, and tunes the display threshold per user because people disagree about the cost of a false positive more than they disagree about content. Scaled down: an override weighs 1.0, accepting the default weighs 0.25, and the factory value starts with a prior rather than at zero. It still works out at about two corrections - the difference is that the number falls out of the weights rather than being picked, and leaving the default alone pushes back. The factory value is never destroyed; it is a default, so it is still one click away.8
Adaptive densityunclaimed
Scan velocity
Watches how fast you move through a list and compacts it when you are scanning, opens it up when you settle to read.
Onboarding checklistDoc
On-call runbookDoc
Offsite planningDoc
Design tokensDoc
Deploy pipelineDoc
Brand guidelinesDoc
Q3 retrospectiveDoc
Hiring loopDoc
Incident 402Doc
Roadmap draftDoc
Pricing modelDoc
Support macrosDoc
Flick through it quickly - the rows tighten so more fits. Stop, and they open again. Keep flicking, and it opens anyway after four seconds.
Scroll distance over elapsed time. Past roughly 700px per second nobody is reading, they are looking for something, so the rows tighten and more fits on screen. Stopping for more than a moment reverses it - and so does four seconds of continuous scrolling, because the naive version of this has a documented failure: Glide's preloader pauses image work during a fling, and a user who flings continuously sees nothing but placeholders until the queue drains. Any velocity rule needs a bound on how long the degraded state may persist. Velocity is also the only signal here that is not a click at all - it is a physical fact about a hand, and it says something about intent that no button press does. It is the one mechanism on this page with no real interface precedent: everybody uses scroll velocity to decide what to fetch, and essentially nobody uses it to decide what to show.9
Ephemeral menuunclaimed
Onset
Likely items arrive instantly and the rest fade in behind them. Nothing moves, nothing hides - the only thing that adapts is when you can see it.
Pick something, then reopen the menu. Nothing will move - watch what arrives first instead.
The best idea in the adaptive-UI literature, and seventeen years on still effectively unshipped. Predicted items are painted immediately; the rest fade in over half a second. Nothing moves, nothing is hidden, and the layout is identical to the static menu. It works because an abrupt visual onset captures attention automatically rather than voluntarily - that is a result from the vision literature, not from interface design, and it means the right item is found without the menu being read. What makes it worth more than everything else here is the failure mode. Every other adaptive technique trades a win-when-right against a loss-when-wrong; across two experiments and 48 participants this one was faster than a static menu when the prediction was good and not significantly slower when it was bad. The predictor here is deliberately the dumbest in the set, the last two things you picked, because the contribution is the output channel and not the model.1011
Key targets
Landing bias
Learns where your finger actually lands relative to where it aims, and moves the invisible boundaries to meet it. Nothing on screen shifts.
A
S
D
F
G
centred
Tap the same key repeatedly, but always a little left of its middle. The boundaries drift left to meet you; the keys stay where they are drawn.
The keyboard on your phone already does this and has never told you. A per-user touch model learns where your finger lands relative to where the key is drawn, and moves the invisible hit boundaries to meet it; the visible keys do not shift, and there is no indication that the touch zones differ from the drawn ones. The constraint that matters is the clamp. Gunawardana, Paek and Meek found that resizing key targets too aggressively can stop people typing what they intended - the interface starts accepting taps on behalf of a key you are not looking at - and proposed anchoring the targets so they cannot run away from their keys. The model here is one number, an exponential moving average of your aim error, anchored the same way. The lesson generalises well past keyboards: adapt what the interface accepts before you adapt what it shows. Hit targets, hover tolerances, drag thresholds, dwell times and undo windows can all be learned without a single pixel moving.12
The common thread is how little machinery any of this takes. The most complex thing here is an exponential moving average. None needs a model, a server, or a consent dialog.
What they do need is a decision about what happens when the guess is wrong. The easy answer is that the interface should degrade to the ordinary version rather than to a broken one - and that answer is necessary and not sufficient. Office 2000’s personalised menus satisfied it completely: every command stayed reachable, one chevron away. They failed anyway, badly enough that Microsoft eventually abandoned adaptation and shipped the Ribbon instead4. The cost of a wrong guess there was never a misclick. It was your spatial memory, because position is a cache and reordering invalidates it on every interaction including the ones the ranking got right; and it was discoverability, because a command you have never used is by construction the command a frequency-ranked system hides.
So the real test is not whether being wrong costs a click. It is whether being wrong costs a model - the map someone has built of where things are. That is why the palette promotes into a small zone instead of sorting one list3, and why the menu adapts the moment an item becomes visible rather than where it sits. Adapt salience before position; if you must move something, move a bounded few into a region set aside for it, and leave the rest exactly where they were.
The last piece is the way out. A system that learns from correction can learn the wrong thing - the iOS keyboard dictionary will absorb a typo you make often enough and then start correcting the real spelling to it - and what ships alongside it there is a single button, not a settings tree. There is one below, and it empties every model on this page.
Back to factory.
Notes and sources
Where a number in these components is not arbitrary, this is where it came from.
Mozilla. Address Bar — Ranking. Firefox Source Docs.docsSource of every constant in the palette: “the update is done as use_count * .9 + 1”, asymptotic to 10; a 0.975 decay on daily idle; removal below 0.975^90 = 0.1, or ninety days unused.
Glide. RecyclerView integration — RecyclerViewPreloader.docsScroll velocity and direction driving how much work to do. The most widely deployed velocity signal in software, and it decides what to fetch rather than what to show.