Skip to content

doctor: a service is "installed" only if the OS will actually start it - #96

Merged
myobie merged 1 commit into
mainfrom
fix/doctor-checks-service-enablement-not-presence
Aug 30, 2026
Merged

doctor: a service is "installed" only if the OS will actually start it#96
myobie merged 1 commit into
mainfrom
fix/doctor-checks-service-enablement-not-presence

Conversation

@myobie

@myobie myobie commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Finding 10 of the 2026-08-29 review.

The hole

gather set service_installed = Some(service_unit_path().exists()). Presence of the unit file is not enablement. A service disabled during an incident (systemctl --user disable, or launchctl disable) with its unit file left in place reported ok service installed and managed by the OS. After a reboot, no daemon starts, and the last thing anyone read said it was fine. src/ca.rs was fixed for exactly this presence-is-not-the-property mistake (is_installed verifies rather than checks a path); the service check was not.

The fix

service::service_enablement() queries the manager and returns Enabled | PresentNotEnabled | NotInstalled | Unknown:

  • Linux: systemctl --user is-enabled fabric.service.
  • macOS: whether launchctl print <target> reports the label loaded.

Doctor reports PresentNotEnabled as a problem ("the service is installed but not enabled, so it will not start after a reboot") distinct from NotInstalled, because the two have different repairs.

Tests

The output interpreters (interpret_systemd_is_enabled, interpret_launchd) are pure and cfg-free, so they run on any host: they pin that enabled reads as enabled while disabled/static/masked/linked/empty read as present-not-enabled, and that a missing unit is NotInstalled whatever the query says. a_present_but_not_enabled_service_is_a_problem_not_ok pins the diagnose-level verdict. The subprocess call itself is the untestable part, like the version probe beside it.

Full suite green locally on macOS.

@myobie
myobie force-pushed the fix/doctor-checks-service-enablement-not-presence branch 2 times, most recently from 708779b to 4eefbf4 Compare August 30, 2026 11:53
Finding 10 of the 2026-08-29 review. doctor set service_installed from the
unit file's mere presence, so a service disabled during an incident with its
unit left in place reported "installed and managed by the OS" — and after a
reboot no daemon started. The CA trust check was fixed for exactly this
presence-is-not-the-property mistake; the service check was not.

service::service_enablement() now queries the manager: on Linux
`systemctl --user is-enabled fabric.service`, on macOS whether launchd has
the label loaded. It returns Enabled, PresentNotEnabled, NotInstalled, or
Unknown, and doctor reports the middle state as a problem with its own
repair, because "present but not enabled" and "never installed" are different
faults. The output interpreters are pure and tested on any host; the
subprocess call is the untestable part, like the version probe beside it.

Proof: a_present_but_not_enabled_service_is_a_problem_not_ok pins that a
disabled-but-present service reads as a problem and not as enabled, with the
healthy case still Ok. Two interpreter tests pin the manager-output mapping.
@myobie
myobie force-pushed the fix/doctor-checks-service-enablement-not-presence branch from 4eefbf4 to d53b5dc Compare August 30, 2026 12:01
@myobie
myobie merged commit 2db03c4 into main Aug 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant