Report format¶
--format json and --format yaml produce the same structure. It's versioned by
schema_version; fields may be added in later versions, but existing ones keep
their meaning until the version changes. These two formats can be read back by
pydebuprep convert.
{
"schema_version": "1",
"tool": {"name": "pydebuprep", "version": "0.3.1"},
"generated_at": "2026-10-28T12:00:00+00:00",
"host": {
"hostname": "web1",
"os_id": "debian",
"os_version": "13",
"codename": "trixie",
"kernel": "6.12.0-1-amd64",
"is_root": true
},
"baseline": {
"path": "/var/lib/pydebuprep/snapshots/20261027T100000Z.json",
"created_at": "2026-10-27T10:00:00+00:00",
"os_version": "12",
"hostname": "web1"
},
"summary": {
"critical": 1, "warning": 0, "info": 1,
"ok": 30, "skipped": 4, "error": 0,
"exit_code": 2
},
"results": [
{
"id": "apt-sources",
"title": "APT sources",
"category": "release",
"status": "findings",
"skipped_reason": null,
"error": null,
"findings": [
{
"severity": "critical",
"title": "No enabled repository for the Debian archive",
"detail": "No enabled source points at the distribution's own archive, ...",
"evidence": ["..."],
"remediation": ["Add the Debian archive for trixie to /etc/apt/sources.list.d/", "sudo apt update"],
"references": []
}
],
"baseline_diff": []
}
]
}
Fields¶
Top level
| Field | Type | Meaning |
|---|---|---|
schema_version |
string | "1" |
tool |
object | name and version of pydebuprep |
generated_at |
string | ISO 8601 time the report was made (UTC) |
host |
object | see below |
baseline |
object or null | the snapshot compared against, or null |
summary |
object | counts and the exit code |
results |
array | one entry per check, in report order |
host: hostname, os_id (debian, ubuntu), os_version (13,
24.04), codename, kernel (the running kernel), is_root (whether the report
ran as root).
baseline: path, created_at, os_version and hostname of the snapshot.
summary: the number of findings per severity (critical, warning, info)
and of checks per status (ok, skipped, error), and the exit_code the run
returned. Findings hidden with --min-severity are still counted.
results[]
| Field | Type | Meaning |
|---|---|---|
id, title, category |
string | the check |
status |
string | ok, findings, skipped or error |
skipped_reason |
string or null | why it was skipped |
error |
string or null | why it failed |
findings |
array | what it found now |
baseline_diff |
array or null | changes since the baseline; null when the check doesn't compare or there's no baseline |
Findings: severity (critical, warning, info), title, detail, and
the lists evidence, remediation and references.
todo (only with --todo): the TODO list,
an array of {"severity", "check", "title", "steps"}. severity and check are
null for the items that aren't findings (a check that failed to run, running as
root, the confirmation run). convert accepts reports with or without it.
Examples¶
# Hosts and their critical/warning counts, from collected reports
jq -r '[.host.hostname, .summary.critical, .summary.warning] | @tsv' reports/*.json
# Every critical finding with its check
jq -r '.results[] | .id as $id | .findings[] | select(.severity == "critical") | "\($id): \(.title)"' report.json