Skip to main content

Module hot_reload

Module hot_reload 

Source
Expand description

Hot config-as-data reload — apply a verified bundle at the turn boundary, with no process restart (see the update PRD and crate::compat / crate::stager).

This is the OTA-instant layer. A config-as-data bundle — system prompts, persona definitions, the tool catalog, model routing — is staged, verified, and then swapped into a single in-memory handle the turn loop reads at turn-start. The next turn of any conversation picks up the new bundle; an in-flight turn keeps the bundle it captured when it began. No binary changes, no restart.

§The turn-boundary handle

HotConfig<C> is an atomically-swappable pointer to the live config-as-data value. A turn reads it exactly once, at turn-start, via HotConfig::current — the returned Arc is that turn’s pinned snapshot. Because the snapshot is an owned Arc, a swap that lands while the turn is still running does not disturb it: the in-flight turn finishes on the value it started with, and only the next HotConfig::current observes the new value. That is the whole boundary guarantee, and it holds because the read happens once, at the start.

The control plane already runs exactly this pattern for one config dimension — model routing is held behind an Arc<ArcSwap<ModelRef>> and read once per turn at dispatch, so a live model set lands on the next turn of every conversation. HotConfig generalizes that mechanism to the whole config-as-data surface and ties it to the verify + classify + rollback machinery below.

§The classifier gate

Only a bundle that classifies Compatibility::Hot takes this no-restart path. ensure_hot refuses any other verdict, and apply_hot_reload routes a StagedBundle through the compat interlock (StagedBundle::evaluate) so a bundle authored against a different runtime is refused before anything is applied. A warm or cold change is a binary release, delivered on the other channel and picked up on restart — it never arrives here as a config bundle.

§Reusing the stager

The apply itself reuses crate::stager wholesale: the same signature verify (an unverified bundle is never applied), the same health check, and the same pointer-flip rollback. The only thing that differs for a hot reload is the Activator — instead of a symlink or image swap, it is a config-pointer swap on a HotConfig. HotConfigActivator is that activator, so a caller drives an ordinary Stager whose activator swaps the live config value, and a failed health check flips the value back to the previous bundle just as a binary rollback flips a symlink back.

Structs§

HotConfig
An atomically-swappable handle to the live config-as-data value the turn loop reads at turn-start.
HotConfigActivator
A config-pointer-swap Activator: the hot-reload analog of the stager’s symlink or image swap.

Enums§

HotReloadError
Why a hot config reload was refused or could not complete.

Functions§

apply_hot_reload
Apply a staged config-as-data bundle to the live config via stager, only if it classifies hot against running.
ensure_hot
Gate a classification verdict onto the hot path: Ok only for Compatibility::Hot.