Skip to content

CLI Contract

This document defines the public command-line contract for pi-doctor.

Stability Levels

pi-doctor exposes two kinds of output:

  • Machine-facing output: intended for automation and treated as stable within a schema version.
  • Human-facing output: intended for people reading terminal output and allowed to evolve between releases.

Exit Codes

pi-doctor check maps impact-based report status to process exit code:

  • 0: healthy
  • 1: warning
  • 2: degraded
  • 3: critical

Any internal CLI failure returns:

  • 4: command execution or rendering failure

The following commands return 0 on success:

  • pi-doctor explain <topic>
  • pi-doctor doctor <target>
  • pi-doctor support-bundle
  • pi-doctor completions <shell>
  • pi-doctor --help
  • pi-doctor --version

Timeout Contract

All commands accept the global --timeout <SECONDS> option. The default is three seconds per external command. When a probe command exceeds the timeout, the process is terminated, the probe reports timed_out in JSON probe_health, and check continues with the remaining probes.

Output Format Stability

Stable

These outputs are part of the public automation contract:

  • pi-doctor check --json
  • pi-doctor --json doctor camera
  • pi-doctor --json doctor gpio
  • pi-doctor --json support-bundle
  • report.json inside pi-doctor support-bundle

For these outputs, the following are stable within a given schema_version:

  • The semantic meaning of top-level fields
  • Exit-code mapping for check
  • Enum values such as overall_status
  • Enum values such as probe_health[].outcome
  • Finding impact values and their rollup to overall_status
  • The deterministic ordering of groups and findings
  • UTF-8 text output terminated by a trailing newline from the CLI

Additive fields may be introduced in a future minor release, but breaking changes require a schema_version change.

Not Stable

These outputs are human-oriented and should not be parsed as a strict API:

  • pi-doctor check without --json
  • pi-doctor explain <topic>
  • pi-doctor doctor <target>
  • manifest.txt and report.txt inside support bundles
  • --help and shell completions formatting

They are tested for regressions, but wording, spacing, and presentation may change between releases.

Logging Contract

Logs are out-of-band diagnostics and are not part of the report JSON contract.

  • Logs are controlled by PI_DOCTOR_LOG.
  • Logs go to stderr.
  • Set PI_DOCTOR_LOG_FORMAT=json to emit JSON-lines logs with level, target, and redacted message fields.
  • Normal --json command output remains on stdout.
  • Consumers should not treat log fields as a stable machine-report schema.

Example:

PI_DOCTOR_LOG=debug PI_DOCTOR_LOG_FORMAT=json pi-doctor --json check > report.json 2> pi-doctor.log.jsonl

Read-Only Probe Contract

pi-doctor diagnostics are read-only. The tool does not write to system paths, load kernel modules, enable interfaces, edit boot configuration, or restart services during diagnostic commands.

Files and directories read by probes:

  • /proc/device-tree/model
  • /proc/cpuinfo
  • /proc/sys/kernel/osrelease
  • /proc/sys/kernel/arch
  • /etc/os-release
  • /usr/lib/os-release
  • /boot/firmware/config.txt
  • /boot/config.txt
  • /sys/class/thermal/thermal_zone*/type
  • /sys/class/thermal/thermal_zone*/temp
  • /dev directory names matching video*
  • Python EXTERNALLY-MANAGED marker path reported by python3 -c 'import sysconfig; ...'

Executables checked for presence in PATH:

  • rpicam-hello
  • libcamera-hello
  • pinctrl
  • raspi-gpio
  • gpioinfo
  • gpiodetect
  • python3
  • dpkg-query

External commands run by probes:

  • vcgencmd get_throttled
  • vcgencmd version for support bundles
  • rpicam-hello --list-cameras
  • libcamera-hello --list-cameras
  • pinctrl
  • python3 --version
  • python3 -c 'import sys; print(sys.executable)'
  • python3 -c 'import sys; print(int(sys.prefix != sys.base_prefix))'
  • python3 -c 'import sysconfig; print(sysconfig.get_path("stdlib"))'
  • dpkg-query -W -f=${Status} python3-picamera2
  • dpkg-query -W -f=${Status} python3-gpiozero

Command output is bounded. A command that exceeds the output limit is reported as command_failed in probe_health and does not block the rest of the report.

Support Bundle Privacy Contract

pi-doctor support-bundle writes sanitized bundles by default. Use --dry-run to print the complete collection plan without reading probe data or writing files. Use --output DIR to choose the output directory.

Sensitive mode requires both flags:

  • --include-sensitive
  • --acknowledge-sensitive-data

Sanitized bundles redact common personal and secret-bearing patterns including home paths, hostnames, usernames, IPv4 and IPv6 addresses, MAC addresses, serial numbers, Wi-Fi SSIDs, URLs, tokens, credentials, device IDs, and private-key blocks. Every bundle contains privacy.txt and a manifest.txt with SHA-256 hashes for payload files.

Config Rule Contract

config.txt diagnostics are section-aware:

  • Repeating the same dtoverlay name in the same section is reported.
  • Different dtoverlay values in the same section are allowed.
  • Repeating a dtparam with the same value in the same section is allowed.
  • Repeating a dtparam with conflicting values in the same section is reported.
  • The same overlay or parameter may appear in different sections without being treated as a duplicate.

These findings describe observed entries in the parsed source file. They do not yet resolve include files, inactive conditional sections, or the final effective boot setting after [all], board-specific sections, and later overrides are layered.

Compatibility Guidance

If you are automating against pi-doctor:

  • Prefer pi-doctor check --json
  • Gate on schema_version
  • Use process exit codes only for coarse health status
  • Ignore unknown JSON fields