Five items had been sitting in the Service Configuration section for a while: mail relay and filtering, WebDAV access, log rotation, service certificates, and a service manager. None looked hard individually. Together they were an instructive stretch of work, mostly because three of the five hid a real bug that only showed up when run against a live development server rather than a mocked test suite.
Mail filtering was simpler than expected in one direction and needed care in the other. Recipient-side blocking had to be wired into the same builder that already manages the mail server’s other restrictions, so that saving one setting could never drop another. Testing against the live configuration, which the mocked suite passed without catching, also found that a validation list hadn’t been updated for the new option, so the first live save failed. Both were fixed and reverified.
WebDAV went the way Directory Privacy had already gone, using the web server’s own WebDAV module rather than a separate daemon, with the required package installed from the admin toggle and gated on the configuration test passing before anything reloads. Verified with a real account and authenticated requests, then torn down cleanly.
Log rotation is where the sharpest lesson showed up. The original plan used a second panel-owned rotation file alongside the stock one; reading the tool’s debug output showed it would have silently ignored the second file, so a setting would have looked saved and never taken effect. The real fix was simpler: manage the stock file directly. That also surfaced a missing write permission, which caused a read-only error on the first live save. Both were fixed and verified with a real save, a dry run, and a revert to defaults.
Service certificates ended up the smallest, deliberately. The panel issues one certificate and mail reuses it, so the honest scope was making that sharing visible rather than building a second issuance path nobody needed.
The service manager was the one place a synchronous mistake could be worse than a rejected save, given an earlier lesson about a service reload interrupting the request that triggered it. Every start/stop/restart goes through a queued job, and stopping critical services is refused at several layers. Proved live: a stop attempt was rejected, and a real restart went through the queue while the triggering request came back unaffected.
One more fix: the development server’s licence had been a placeholder that never validated, and was replaced with a proper internal one issued through the normal licensing path.
Every item shipped with its own tests, live verification, and commit, and the whole batch landed as one version bump.