Rust Hygiene Audit
Turn a fuzzy "clean up the codebase" request into a set of evidence-backed,
deduplicated, parent/child GitHub issues — without flooding the tracker with
smells. The guiding principle: every issue must cite real file:line evidence
that survived an adversarial check, and must not duplicate an open issue.
This skill is for hygiene/DRY/lint work, not behavior changes. It produces
issues and field assignments; it does not edit compiler logic. Keep parity work
(tsc matching) in the owner skills.
The four phases
Run them in order. Phases 1–2 are analysis; 3–4 are writes — confirm scope with the user before mass-creating issues unless they already said "create them".
1. Measure the Clippy posture (prevention evidence)
The cheapest lever against future debt is a tighter lint floor, so quantify what the current floor lets through before proposing changes.
python3 .agents/skills/rust-hygiene-audit/scripts/measure_clippy.py --worktree . --out /tmp/hygiene
This runs cargo clippy --workspace --lib -- -W clippy::pedantic -W clippy::nursery
(no files touched), aggregates warnings per lint, and prints a promote vs
defer triage. Read references/lint-triage.md for the rationale behind which
lints are worth promoting in a compiler (numeric casts and must_use/doc
pedantry are mostly intentional; idiom/ownership lints are high-signal). The
count and triage become the body of the clippy-posture epic.
Disk note: a cold workspace clippy build needs ~8–12GB. If low, reclaim merged
worktree caches first (see tsz-disk-cache-hygiene).
2. Fan out the audit (find + verify)
Drive the bundled workflow, which fans out per-crate DRY auditors and cross-cutting concern auditors, dedups against open issues, then adversarially verifies every candidate against the real source before authoring full issue bodies:
Workflow({ scriptPath: "scripts/agents/hygiene-audit-workflow.mjs" })
Before launching, snapshot the open issues the auditors dedup against:
gh issue list -R <owner>/<repo> --state open --limit 300 --json number,title,labels > /tmp/hygiene/open-issues.json
The workflow returns { epics, children, dropped, stats }. children carry
verified evidence and full body_md. dropped records findings that
overlapped an existing issue — surface these so the user sees the dedup worked.
Tune the auditor list (crates + concerns) in the workflow's CRATES/CONCERNS
arrays for the target repo. The verify stage defaults to reject on weak
evidence — that is the anti-spam gate; do not weaken it.
3. Create the issue hierarchy
Author epic body_md (summarize the theme + bake in the measured clippy data
for the lint epic), then create epics and children with native sub-issue links:
python3 .agents/skills/rust-hygiene-audit/scripts/create_issues.py \
--repo <owner>/<repo> --specs /tmp/hygiene/result.json --apply
Match the repo's existing issue conventions. For tsz that is the
techdebt(scope): title + the template in references/issue-template.md
(## Summary with a structural rule → ## Evidence → ## Why it matters →
## Proposed fix (sized S/M/L) → ## Risks / coordination). The script writes
a ## Child issue map into each epic as a durable fallback even when native
linking succeeds.
4. Assign Priority / Effort Fields
python3 .agents/skills/rust-hygiene-audit/scripts/assign_fields.py \
--repo <owner>/<repo> --specs /tmp/hygiene/result.json --apply
Discovers the repo's Priority/Effort single-select issue Fields by name,
then assigns by rule. Default priority ranking is correctness > speed >
tech-debt (map to High/Medium/Low; reserve Urgent for urgent/panic
labels). Effort comes from the audit size (S/M/L → Low/Medium/High) and
epic-scale → the top level. See references/github-fields-api.md for the API
gotchas — they are easy to get wrong:
- Sub-issues:
gh api -X POST .../issues/<parent>/sub_issues -F sub_issue_id=<db_id>—-F(integer) not-f(string); the id is the issue database id, not its number. setIssueFieldValueworks withreposcope, butcreateIssueField/updateIssueField(changing a field's options) needadmin:org. If you must add an option and lack the scope, ask the user to add it in the UI or fall back to the existing options.
What good output looks like
- Issues cite ≥2 real sites for any DRY claim and name the structural rule.
- Duplication that already drifted into a parity bug is flagged as such — that is the highest-value finding, not a cosmetic one.
- Nothing duplicates an open issue (the
droppedlist proves the check ran). - A small number of strong epics, each with actionable PR-sized children.
What to avoid
- Smell-only issues with no
file:lineevidence. - Mass-creating before the user has agreed to issue creation.
- Architecture-boundary refactors that overlap an active campaign — check open issues first and let the auditors dedup.
- Fixture-name / rendered-output string checks in any proposed fix (repo anti-hardcoding gate).