Owns the popup lifecycle and the (debounced via generation tokens)
query plumbing. The host calls sync(host) after every edit; the
controller decides whether to open, refresh, or close the popup.
Fire-and-forget redraw signal owned by the controller and invoked
from the spawned query task. The host wires this to its event loop
(e.g. tx.send(AppEvent::Redraw)).