fix(settings): restart the settings daemon in one step - #386
Conversation
The settings page renders the running rev from AGENT_BOX_REV, which the daemon reads from its environment once at startup. After a rebuild the card can therefore advertise an update that is already applied. Observed on the deployed box: generation 28 carried rev 79e5222, but the live daemon still held generation 27's dcc9a2a and reported "agent-box update available - 40 commits" (exactly dcc9a2a..master). The update service itself said "already current" and did not rebuild, so the two disagreed with no way for the operator to tell which was right. The unit is socket-activated. NixOS's default two-step restart stops it in the OLD configuration, before the new one's daemon-reload, so a client holding the settings page open reconnects into that window; the socket restarts the daemon from systemd's cached old unit definition and switch-to-configuration's later start step finds it already running. The timestamps match: the settings daemon came up at 17:47:36, one second BEFORE the supervisor and the webhook receiver, which are not socket-activated and picked up the new definition correctly. stopIfChanged = false makes it a single `systemctl restart` after the new definition is loaded, which closes the window. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 4 remain after this review. 📝 WalkthroughWalkthroughThe systemd settings service definitions now disable stop-on-change behavior. The golden service fixture includes the generated ChangesSettings daemon lifecycle
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This localized change makes the settings daemon restart under the updated configuration, preventing stale settings from being shown after an update. The listed checks pass, and no actionable merge-blocking risk remains. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (3 skipped: 3 unsupported.) ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
The symptom
The settings page reported an update that was already applied:
Meanwhile
agent-box-update.servicesaidalready currentand refused to rebuild. Both pins were at79e5222. An operator has no way to tell which of the two is right.The cause
The page renders
AGENT_BOX_REV, which the daemon reads from its environment once at startup (render_update_line(),modules/src/settings-daemon.py). On the deployed box the live process still held generation 27's rev while systemd's unit definition, the pin file and the update unit all carried generation 28's:/proc/<pid>/environ)dcc9a2a8…(gen 27, #357)systemctl show,/etc/nixos/agent-box-pin.nix79e52224…(#381)dcc9a2a8..masteris exactly 40 commits, which is the number the card printed.79e5222..masterwas 0.The unit is socket-activated (
Requires=agent-box-settings@%i.socket). NixOS's defaultstopIfChanged = truestops it in the old configuration, before the new one'sdaemon-reload. A client holding the settings page open reconnects into that window, the socket starts the daemon again from systemd's cached old unit definition, andswitch-to-configuration's later start step finds it already running.Start timestamps on the box support this: the settings daemon came up at 17:47:36, one second before
agent-box@agentandagent-box-webhook@agentat 17:47:37. Neither of those is socket-activated, and both picked up the new definition correctly (the receiver reports0.23.0, this PR's parent #381).The fix
stopIfChanged = falseon the settings drop-in makes it a singlesystemctl restart, issued after the new definition is loaded. Rendered result, the whole behavior change:This does not make the rev dynamic — the daemon still reads it at startup. It makes the restart reliable, so startup happens under the new configuration. Moving the rev to a file read per request would be the thorough fix; it is not needed if the restart is correct.
Verification
Regenerated with
nix run .#assembleandnix run .#update-golden. Checks run natively onaarch64-linux:module-generated-up-to-dategolden-snapshotassemble-module-escapingmulti-usermodule-single-filesettings-page,golden-snapshotandmemory-protectionforx86_64-linuxevaluate cleanly (.drvPath); the VM runs themselves need an x86 host, so CI covers those.Only the
webgolden profile changed. Thevmprofile hasweb.enableoff, so it ships no settings unit.🤖 Generated with Claude Code
https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN