Hysteresis and Debounce Filter¶
Switch-damping filter — instantiates Context-Keyed Representation Switching
Sits between the context signal and the switch, damping it so momentary noise or a value hovering at the boundary can't trigger rapid back-and-forth map changes.
A context signal that hovers at a threshold, or carries noise, will make a naive switch flap — flipping between two representations again and again, paying the cost of each change and settling on neither. Hysteresis and Debounce Filter sits between the signal and the switch to prevent that. Its defining job is not choosing which map but deciding whether a candidate switch is real enough and worth its cost: it requires the signal to clear a band (different thresholds to switch in versus out) and to persist for a dwell time before it acts, and it charges each switch against a budget so switch frequency stays bounded. It trades a little responsiveness for a lot of stability — the deliberate opposite of a hair-trigger.
Example¶
A cloud service autoscales between 3 and 4 instances as load hovers right at the threshold. Without damping it flaps: CPU crosses the line, a fourth instance spins up (paying a cold-start), load dips, it scales back down, load rises again — churning every minute and never stable. The filter fixes this with two levers. A hysteresis band scales up at 75% CPU but only down below 55%, so the boundary is no longer a single hair-trigger line. A debounce/cooldown requires the new condition to hold for, say, ≈5 minutes before acting, so a momentary spike is ignored. Now the autoscaler commits to a level and stays, and the switch-cost budget caps how often it may change at all — trading a slightly slower reaction for an end to the thrash.
How it works¶
Its distinguishing move is that it acts on the switch decision, not the destination. Two coupled levers do the work: a deadband — separate switch-in and switch-out thresholds — so a value sitting on the boundary does not oscillate, and a debounce/dwell requirement so a transient spike must persist before it counts. Layered on top, a switch-cost budget bounds how many switches are permitted per window, so even a genuinely wobbling signal cannot thrash the system. Every lever trades reaction speed for stability; the filter's whole purpose is to spend the former to buy the latter.
Tuning parameters¶
- Deadband width — the gap between the switch-in and switch-out thresholds. Wider kills flapping decisively but adds lag and can straddle a real, small change without ever acting on it.
- Debounce / dwell time — how long the new context must persist before the switch fires. Longer is calmer and more noise-immune but slower to react to a genuine change.
- Switch-cost budget — the maximum switches allowed per window. Tighter caps thrash but can suppress legitimately rapid context changes.
- Asymmetry — different stickiness entering versus leaving a context — e.g., quick to drop into a safe mode, deliberately slow to leave it.
When it helps, and when it misleads¶
It earns its place whenever switching is costly and the context signal is noisy or hovers at a boundary — exactly the conditions that produce thrash.
Its failure is the mirror of the problem it solves: too much hysteresis makes the system sluggish, and a band that is too wide or a dwell that is too long will hide a genuine fast change, leaving the wrong map running straight through a real transition. The classic misuse is widening the band to silence a switch that is actually firing correctly — dismissing a real, repeated signal as "noise" because the switching is inconvenient. The discipline is to size the band and dwell to the measured noise, not to the annoyance, and to keep the suppressed signal observable so a masked real trend can still be seen.[1]
How it implements the components¶
switch_hysteresis_rule— the deadband and dwell logic are the hysteresis rule: asymmetric thresholds plus a persistence requirement that damp flapping.switch_cost_budget— it enforces a ceiling on switch frequency, accounting for the cost of each change so the system cannot thrash even under a wobbling signal.
It does NOT decide which switches are legal or which map a state selects — legality is Finite-State Map Selector's and the key→map lookup is Context-to-Map Routing Table's; the filter only governs the timing and frequency of switching.
Related¶
- Instantiates: Context-Keyed Representation Switching — it keeps switching stable under a noisy context signal.
- Consumes: the raw context/cue signal; it feeds a stabilized switch decision to the selector.
- Sibling mechanisms: Finite-State Map Selector · Context-to-Map Routing Table · Gated Expert Router · Active-Map Status Indicator · Safe Default-Map Fallback
Notes¶
It changes the timing and frequency of switching, never the destination. A debounce placed on top of a wrong selector only makes the wrong switches slower, not right — the filter presumes the selection logic beneath it is sound and merely protects it from acting on noise.
References¶
[1] Hysteresis (a deadband with distinct switch-in/switch-out thresholds, as in a thermostat or a Schmitt trigger) and debounce (ignoring transitions until a signal settles) are the standard cures for a hair-trigger. Both work by trading responsiveness for stability — which is exactly why over-widening them to quiet an inconvenient-but-correct signal is the misuse to watch for. ↩