Context
`bin/base-demo-services` contains two functions that both dispatch on `check.type`: `check_service()` (performs the actual probe) and `health_label()` (returns a display string). They are structurally parallel but maintained separately. Adding a new check type requires updating both, and there is no guard that catches a mismatch.
Currently `health_label()` also has a special-case for `health_url` at the top that doesn't exist in `check_service()`, which already caused the `demo-console` bug (see #87) and could cause similar divergence for future check types.
Scope
- Refactor so that each check type produces both its probe result and its display label from a single code path — for example, a small per-type function or a `CheckResult` named tuple that carries `(ok: bool, label: str, detail: str)`.
- Remove the top-level `health_url` special-case from `health_label()` or make it consistent with how `check_service()` resolves the URL.
- Keep the public behavior of `cmd_status` and `cmd_check` identical.
- Update tests to verify both the label and the probe result come from the same logical path.
Validation
- All existing service status and check tests pass.
- Manually verify `services status` and `services check` output is unchanged for all check types (file, http, compose, command, none).
- `./tests/validate.sh`
Context
`bin/base-demo-services` contains two functions that both dispatch on `check.type`: `check_service()` (performs the actual probe) and `health_label()` (returns a display string). They are structurally parallel but maintained separately. Adding a new check type requires updating both, and there is no guard that catches a mismatch.
Currently `health_label()` also has a special-case for `health_url` at the top that doesn't exist in `check_service()`, which already caused the `demo-console` bug (see #87) and could cause similar divergence for future check types.
Scope
Validation