repo-hygiene-audit-skill/repo-hygiene-audit/references/findings-format.md
Travis Herbranson 249055fe99 Fix .gitignore swallowing references/findings-format.md
The findings-*.md rule (for generated timestamped reports) also matched the
findings-format.md reference doc, so it was never tracked. Scope the rule to
digit-prefixed names (findings-[0-9]*) and add the missing reference.
2026-05-23 06:50:37 -04:00

3.1 KiB

Findings output format

Three renderers, one finding model. Pick the format for the consumer:

  • text — terminal triage. Summary line, full INVENTORY (every repo, clean ones included), then findings grouped by category.
  • md — phase-mapped markdown. Each finding is a - [ ] checkbox under the remediation-plan phase heading it belongs to, so a run pastes straight into the project plan as actionable items.
  • json — machine-readable for week-over-week diffing and automation.

Finding model

Every finding is one record:

Field Meaning
domain homelab / pbs / docker (the Obsidian vault is out of scope by default — see check-catalog.md)
repo Directory name within the domain
path Absolute path
category SECURITY / AUDITABILITY / CLEANUP / GIT_STATE / DOCS
severity high / medium / low / info
check Stable check id (e.g. no-git, env-world-readable:.env)
detail Human-readable description of what was found
hint Suggested remediation (informational — the skill does not apply it)
key domain/repo:check — stable identifier for dedup/diffing (JSON only)

The key is deliberately stable across runs: a finding that persists keeps the same key, so diffing two JSON runs cleanly separates new drift (keys that appeared) from remediated items (keys that disappeared).

Category → phase mapping

This is how findings line up with the repo-hygiene-remediation plan, so the recurring review feeds the same backlog structure the original audit used:

Category Plan phase
SECURITY Phase 2 — Security remediation
AUDITABILITY Phase 3 — Unblock un-auditable repos
CLEANUP Phase 4 — Cross-repo cleanups
GIT_STATE Git state (review before commit/merge)
DOCS Docs (audit follow-up)

JSON shape

{
  "generated": "2026-05-22T23:05:00",
  "host": "herbys-dev",
  "repos_scanned": 39,
  "summary": {
    "by_severity": {"high": 11, "medium": 19, "low": 23, "info": 9},
    "by_category": {"SECURITY": 5, "AUDITABILITY": 9, "CLEANUP": 8,
                    "GIT_STATE": 27, "DOCS": 13}
  },
  "inventory": [
    {"domain": "docker", "repo": "authelia", "path": "...",
     "is_git": false, "owner": "root", "git_owner": "", "group": "root",
     "branch": "", "finding_count": 2}
  ],
  "findings": [
    {"domain": "docker", "repo": "authelia", "path": "...",
     "category": "AUDITABILITY", "severity": "high", "check": "no-git",
     "detail": "directory holds real content but has no .git",
     "hint": "git init + initial commit ...", "key": "docker/authelia:no-git"}
  ]
}

Diffing two runs

python scripts/audit.py --format json -o this-week.json
# ... a week later ...
python scripts/audit.py --format json -o next-week.json

python3 - <<'PY'
import json
a = {f["key"] for f in json.load(open("this-week.json"))["findings"]}
b = {f["key"] for f in json.load(open("next-week.json"))["findings"]}
print("NEW drift   :", sorted(b - a))
print("REMEDIATED  :", sorted(a - b))
PY