CLI reference · 08

halton-meter doctor

Full diagnostic for the local install. `halton-meter doctor` walks every signal `init` checks plus dependency probes, prints copy-paste fixes for any red row, and emits structured JSON for support tickets.

macOS 12+ · Python 3.11+ Reading time 2 min Updated May 11, 2026

halton-meter doctor is the one command to run when something feels off. It walks every diagnostic signal — cert trust, port binding, env vars, launchd / systemd / Task Scheduler health, certifi patch state, cloud pairing state, dependency versions — and prints a concrete next-action for each failure.

It is read-only by default: doctor never modifies state unless you pass --fix (and even then it only applies the named, safe fixes).

Synopsis

halton-meter doctor [--curl] [--json] [--fix] [--apply]
FlagPurpose
--curlAdd a live curl probe through the proxy to a known endpoint. Useful when “everything looks healthy” but captures aren’t landing — pinpoints whether the daemon path is actually reachable.
--jsonEmit the diagnostic as a single structured JSON blob. Attach this to support tickets — every row appears as {name, status, evidence, next_action}.
--fixPrint the fixes that would be applied without applying them. Pair with --apply to execute. Safe fixes only: re-run init steps, clear stale launchctl env, re-patch certifi. Will not touch the SQLite store, will not regenerate the CA cert, will not re-pair cloud.
--applyApply the fixes. Combine with --fix (--fix --apply). Without --fix, --apply is a no-op.

What doctor checks

The reference is daemon/halton_meter/doctor.py. The check list below mirrors the actual rows; failures print a copy-pasteable next step.

SectionSignals
InstallCLI on PATH; correct binary path; daemon version vs latest PyPI; install channel (uv tool / pipx / pip-in-venv); Python interpreter version inside the venv.
Cert~/.mitmproxy/mitmproxy-ca-cert.pem exists; permissions are 0700/0600; the cert is trusted in the OS trust store; the certifi bundle inside the daemon’s venv carries the cert.
SupervisormacOS launchd: com.haltonlabs.meter plus (in apps/full mode) meter.watchdog, meter.edge, and meter.userenv registered and healthy. Linux systemd: halton-meter.service and halton-meter-edge.service enabled and active. Windows Task Scheduler: halton-meter and halton-meter-edge tasks registered, scheduled ONLOGON, last-run-result 0.
Portsedge :8081 (or its renegotiated fallback) is bound, mitm :8090 is bound, FastAPI :8765 is bound, and the bound process is the daemon (not a stale residual).
EnvHTTPS_PROXY, HTTP_PROXY, NO_PROXY, SSL_CERT_FILE, NODE_EXTRA_CA_CERTS, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, GIT_SSL_CAINFO, AWS_CA_BUNDLE set correctly. On macOS apps-mode: launchctl user-domain env mirrors the shell rc. On Linux: rc-file entries detected. On Windows: HKCU env entries present.
System proxymacOS full-mode: networksetup -getsecurewebproxy <interface> reports 127.0.0.1:8081 enabled on every active interface. Linux: not applicable (apps mode only). Windows apps-mode: HKCU Internet Settings\ProxyEnable=1, ProxyServer=127.0.0.1:8081, ProxyOverride=<local>.
Sentinels~/.halton-meter/proxy-managed reflects the actual mode. system_state.json snapshot is intact (uninstall can restore from it).
Loopback bind guardlisten_host and api_host resolve to loopback (or HALTON_METER_ALLOW_NON_LOOPBACK=1 is set with a warning). v0.2.9+.
CloudIf paired: token file at ~/.halton-meter/cloud-credentials.json is 0600; cloud_state row in SQLite matches; base_url is not a placeholder TLD; last sync timestamp is sensible; paused_reason (if any) and the recovery path.
Capture path--curl only: a live request through the proxy to https://api.anthropic.com/ returns a captured row in the SQLite store within 5 s.

Reading the output

Each row is STATUS signal evidence → next action. Statuses:

  • OK — green. No action needed.
  • WARN — amber. Working but degraded; doctor explains what’s missing.
  • FAIL — red. Broken. Doctor names the fix; --fix --apply applies the safe ones.
~ — sample output, abridged
$ halton-meter doctor
OK    install:cli-on-path        /opt/homebrew/bin/halton-meter
OK    install:version            0.2.11  (latest on PyPI)
OK    install:channel            uv-tool
OK    cert:file                  ~/.mitmproxy/mitmproxy-ca-cert.pem  (0600)
OK    cert:keychain-trust        SecTrust evaluation pass
OK    cert:certifi-patch         marker present
OK    supervisor:daemon          com.haltonlabs.meter        PID 94318
OK    supervisor:watchdog        com.haltonlabs.meter.watchdog
OK    supervisor:edge            com.haltonlabs.meter.edge
OK    ports:edge :8081           bound by daemon
OK    ports:mitm :8090           bound by daemon
OK    ports:api :8765            bound by daemon
WARN  env:HTTPS_PROXY            empty in this shell
      → Open a new terminal so the rc block is sourced, or run: source ~/.zshrc
OK    loopback-bind-guard        listen_host=127.0.0.1
OK    cloud:state                ACTIVE   last sync 3s ago
      (1 warning)

Exit codes

CodeMeaning
0All rows OK.
1One or more FAIL rows. Doctor printed at least one next-action.
2One or more WARN rows (no FAILs). Operator may want to act; daemon still works.
3--fix --apply mode: at least one fix could not be applied automatically (e.g. requires admin elevation).

Common follow-ups

  • A FAIL on cert:keychain-trust → re-run halton-meter init and approve the password dialog.
  • A FAIL on cloud:base_url for a placeholder TLD → v0.2.7+ auto-heals on next start. halton-meter stop && halton-meter start.
  • A FAIL on ports:edge :8081 with held by PID <pid> → another process owns the port. See Port already in use.
  • A FAIL on loopback-bind-guardDaemon exits immediately with loopback bind guard.
  • A WARN on env:HTTPS_PROXY → open a new terminal so the rc block sources; or, for GUI apps, quit and relaunch from Spotlight/Dock (macOS) or the Windows tray (after WM_SETTINGCHANGE propagates).

See also