Setting a new routing default showed "A restart is required before dispatch sees this change." It has not been true since the no-restart work landed: `build_router(cfg, ...)` is handed the SAME RouterConfig object the dispatcher holds and `_resolve_profile` reads `cfg.routing.default_profile` per request, so POST /api/config/routing.default_profile mutating it lands on the very next route. The endpoint has been returning "Set as default and active now -- no restart required" the whole time. The page threw that response away and asserted the opposite, so operators were told to bounce a service that had already picked the change up. Confirmed end to end against a live instance before changing anything: POST the key, then /route reports `profile: onlycheaps` with no restart. Three separate strings made the claim, none of them consulting the API -- a sticky banner after every save, the page subtitle, and the delete dialog. The same is true of profile definitions: all three CRUD paths go through `_persist_profile`, which mirrors the write into the running `cfg.profiles` and answers "Saved and live -- no restart required". The fix is not to flip the wording, which would drift again the first time a write genuinely does need a bounce. `_showRestartHint` is gone and the banner renders the endpoint's own `message`, warning-styled only when the message actually asks for a restart. The two prose lines say the write applies to the next request. The page now reports the server instead of holding a second rule about it. Four tests, because the interesting half is the contract, not the string: the write reaches the live config, the endpoint promises no restart, an ordinary allowlisted key still DOES say restart (the exemption is narrow by design and must stay that way), and the page hardcodes no claim of its own. The last one strips `//` lines first -- the comment explaining this fix quotes the old string, and a test that fails on its own rationale is a test nobody keeps. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRQXz5SYZYVWscxS1QqF6U
7.3 KiB
7.3 KiB