repo-hygiene-audit-skill/repo-hygiene-audit/SKILL.md
Travis Herbranson 236616514f Add repo-hygiene-audit skill (Phase 7: repeatable hygiene sweep)
Read-only scripted audit across homelab/pbs/docker/root domains:
git auditability + .git ownership/dubious, .env perms (0660/devprojects),
inline compose secrets, non-git dirs, uv-init stubs, compose naming,
master-vs-main default, dirty trees, worktrees, herbygitea residue, doc
presence. Emits text/json/md findings mapped to remediation-plan phases.

SKILL.md + scripts/audit.py (stdlib-only) + references + packed .skill.
First run: 39 repos, 62 findings, ruff-clean.
2026-05-22 23:11:48 -04:00

5.9 KiB

name description
repo-hygiene-audit Repeatable hygiene audit across the homelab / pbs / docker / root project domains. Runs scripted, read-only checks for git auditability and .git ownership drift, .env file permissions, inline secrets in compose files, non-git directories, uv-init leftover stubs, docker-compose.yml -> compose.yml naming, branch and master-vs-main default-branch state, dirty trees, stray worktrees, and herbygitea SSH-alias residue — then emits a findings report mapped to the remediation-plan phases. Use when asked to audit repos, run a repo-hygiene sweep, check project folders for drift, do the weekly/recurring guided review, or verify repos against conventions before a commit/merge.

Repo Hygiene Audit

Makes the one-time 2026-05-19/20 documentation/repo audit repeatable so the project folders don't silently drift back into inconsistency. The mechanical checks are scripted (scripts/audit.py); the judgement calls (semantic doc freshness, policy decisions) stay with the human/agent driving the review.

This skill is read-only against the trees it scans. It never edits, commits, or pushes anything in the audited repos — it reports. Remediation is a separate, deliberate step the operator drives.

When to run

  • The recurring guided review (current cadence: weekly, manually triggered).
  • After landing a batch of new repos or scaffolds, to confirm they start clean.
  • Before a commit/merge sweep, to catch state that should be resolved first.
  • Whenever asked to "audit repos", "check for drift", "repo hygiene sweep".

The method

The original audit scored docs on a five-dimension rubric — accuracy (heaviest) → freshness → internal contradiction → completeness → role fit — and verified documented commands/paths against the real tree (a confidently wrong doc is worse than a missing one). That semantic scoring is the human part. This skill automates the mechanical enumeration underneath it: sweep every repo in every domain and flag the objective signals that drift produces.

Domains (the four the audit covered):

Domain Roots scanned
homelab /opt/projects/homelab/*
pbs /opt/projects/pbs/*
docker /opt/projects/docker/*, ~/projects/docker/* (compose stacks)
root /opt/projects/wiki-vault, /opt/projects/wiki-context

docker repos are treated as compose stacks: README expected, no per-stack CLAUDE.md (per the locked doc-role convention).

Workflow

Step 1 — Run the scripted sweep

cd repo-hygiene-audit
# Human-readable, all domains (default config):
python scripts/audit.py

# Phase-mapped markdown you can paste into the remediation plan:
python scripts/audit.py --format md -o findings-$(date +%Y%m%d).md

# Machine-readable for diffing week-over-week:
python scripts/audit.py --format json -o findings-$(date +%Y%m%d).json

No third-party dependencies — plain python3 (or uv run python) is enough.

Step 2 — Triage by phase

Findings are grouped into the categories that map onto the remediation plan's phases (see references/findings-format.md):

  • SECURITY (Phase 2) — world-readable / wrong-mode .env, inline compose secrets.
  • AUDITABILITY (Phase 3) — missing .git, dubious ownership, .git/dir owner drift, non-git dirs with content.
  • CLEANUP (Phase 4) — uv-init stubs, compose naming, stale review docs, herbygitea residue, stray backup dirs.
  • GIT_STATE — master-vs-main default, dirty trees, leftover docs-audit branches, unpushed commits, stray worktrees.
  • DOCS — missing README/CLAUDE.md, oversized CLAUDE.md (possible README clone).

Start at high, work down. The INVENTORY block also lists every repo (even clean ones) so you can confirm the sweep saw what you expected.

Step 3 — Semantic doc pass (human judgement)

For each repo with stale-looking docs, apply the five-dimension rubric by hand: read README + CLAUDE.md against the actual tree. The script flags candidates (missing docs, bloated CLAUDE.md, stale review artifacts); it can't judge whether the prose is accurate. That's the reviewer's call.

Step 4 — Decide remediation, don't auto-fix

The hint on each finding is the suggested remediation, not an action the skill takes. Sequence fixes through the normal flow (and the manual-push rule for GitHub-destined repos). For the safe.directory caveat specifically: prefer a scoped safe.directory <path> entry over the * wildcard, which disables the dubious-ownership safety check everywhere.

Step 5 — Persist the run

Save the markdown report alongside the project plan (or as a vault session note) so the next run can diff against it. Drift shows up as new findings; remediation shows up as findings that disappear.

Scripted checks

scripts/audit.py is the engine. Each check is read-only and resilient (one repo erroring never aborts the sweep). Full catalogue with rationale in references/check-catalog.md. Selected flags:

Flag Purpose
--format {text,json,md} output format (default text)
-o, --output PATH write report to a file instead of stdout
--config FILE.json override the domain map ({domain: {scan:[], repos:[]}})
--scan NAME=PATH ad-hoc: scan immediate children of PATH as repos
--repo NAME=PATH ad-hoc: treat PATH itself as one repo
--only CATEGORY restrict output to one or more categories
--fail-on SEVERITY exit non-zero if any finding at/above that severity (CI/automation hook)

Available resources

Resource When to load Purpose
scripts/audit.py Every run The read-only check engine
references/check-catalog.md Interpreting a finding What each check looks for + why it matters
references/findings-format.md Wiring output into the plan Output schema + category→phase mapping