skills/audit-adr-gaps/SKILL.md
Discover undocumented design decisions and challenge each candidate via critic-design before promotion. Rank by impact and reversibility, produce ADR promotion candidates. Treat each candidate as a position arguing for ADR status, not a fact to be filed. Pairs with audit-adr-drift, which scans existing ADRs for drift against code.
npx skillsauth add thkt/dotclaude audit-adr-gapsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Discover design decisions that exist in the code but have no ADR. Each candidate is challenged by critic-design (Step 6.2) before promotion. The final list is what survived the adversarial pass, not what the initial scan found. Produce a ranked list of ADR promotion candidates so the next refactor has a complete decision baseline.
/audit-adr-gaps and /audit-adr-drift form an ADR-baseline audit pair. Run order depends on whether ADRs already exist, not a fixed sequence.
| Repo state | Run first | Then |
| --------------------- | ------------------------------------------------------ | ----------------------------------------------- |
| ADRs exist | /audit-adr-drift (drift between ADR and code) | /audit-adr-gaps (gaps drift cannot see) |
| ADRs absent or sparse | /audit-adr-gaps (mine decisions into ADR candidates) | /audit-adr-drift (verify once ADRs are added) |
$ARGUMENTS holds the full argument string. Parse before use:
--threshold=N: integer, default 400 if unset or non-numeric (must be > 0)--paths=p1,p2,...: comma-separated paths to documents. If unset, auto-detect via Step 2 table--no-challenge: skip the critic-design challenge step (default: challenge runs)| Step | Action |
| ---- | ------------------------------------------------------------------------------------------ |
| 1 | Detect large files exceeding threshold (default >400 lines) |
| 2 | Detect prose documents likely to contain decisions (README, CONTRIBUTING, etc.) |
| 3 | Run language-appropriate reviewer on each large file; cross-reference with existing ADRs |
| 4 | Extract decision-shaped sentences from prose documents; cross-reference with existing ADRs |
| 5 | Tag each candidate with impact (H/M/L) and reversibility (high/medium/low) |
| 6 | Rank initial candidates; spawn critic-design to challenge them (skip if --no-challenge) |
| 7 | Write report to docs/audit/<YYYY-MM-DD>-<HHMMSS>-adr-gaps.md |
| 8 | List post-challenge ADR promotion candidates as follow-up issues |
# Find source files exceeding the threshold
# NOTE: Do not use awk '$1 > t' here. SKILL loader expands `$1` to the second
# whitespace-token of $ARGUMENTS (0-indexed split). Use find+while instead.
bfs <repo-root> -type f \( -name '*.rs' -o -name '*.ts' -o -name '*.tsx' -o -name '*.py' -o -name '*.go' -o -name '*.swift' \) \
-not -path '*/target/*' -not -path '*/node_modules/*' -not -path '*/.git/*' \
-print0 \
| while IFS= read -r -d '' file; do
lines=$(wc -l < "$file")
[ "$lines" -gt "$THRESHOLD" ] && printf '%s %s\n' "$lines" "$file"
done | sort -rn
Default threshold is 400 lines (one-screen ceiling, see rules/development/THRESHOLDS.md).
Scan top-level and docs/ for decision-bearing documents (README, CONTRIBUTING, SECURITY, THREAT_MODEL, ARCHITECTURE, DESIGN, CLAUDE.md / AGENTS.md, Makefile / justfile, linter configs). Full pattern-to-content table: ${CLAUDE_SKILL_DIR}/references/detection-targets.md.
For files exceeding 800 lines (2x threshold), run a triage sub-step first: spawn the reviewer with a "scan first 200 lines and estimate finding density (findings per 100 lines)" instruction, then AskUserQuestion with three options:
skipped_for_size)For files at or below 800 lines, proceed directly to full scan.
For each large file (full or truncated scope), spawn the matching reviewer via Task (same routing as /audit-adr-drift Step 5). The reviewer answers:
incomplete-contract pattern)Findings format: file:line + decision summary + evidence (code comment, naming, module-doc) + documented? (Yes/Partial/No) + incomplete-contract? (Yes/No). The incomplete-contract flag marks code whose comment says what is true but not what must remain true (a missing rule for future contributors); promotion is handled in Step 6.1, with examples in ${CLAUDE_SKILL_DIR}/references/decision-criteria.md.
After collecting findings, cross-reference each one against the ADR directory (if any). Drop findings already covered by an ADR (record count as "ADR-covered (excluded)" in the summary).
For each detected document, find sentences containing decision verbs and check for ADR coverage:
Each match is a candidate. Then for each candidate, search the ADR directory (if any) for cross-reference. Drop candidates already covered by an ADR.
In addition to prose docs, scan source code for per ADR-NNNN / see ADR-NNNN / ADR-NNNN reference patterns:
ugrep -r -n -E "(per |see |governed by )?ADR-[0-9]{4}" --include="*.rs" --include="*.ts" --include="*.tsx" --include="*.py" --include="*.go" --include="*.md" --include="*.toml" .
For each captured ADR id, check whether the matching NNNN-*.md exists in the local ADR directory:
External ADR dependencies are flagged for promotion (write a scout-local ADR that supersedes or imports the external decision). This is impact=H by default because cross-repo ADR drift is silent and hard to detect after the fact.
| Impact | Criteria | | ------ | --------------------------------------------------------------------- | | H | Crosses module boundary, affects public API, or governs 2+ subsystems | | M | Affects single module's internal contract | | L | Local style or naming choice |
| Reversibility | Criteria | | ------------- | ---------------------------------------------------------------- | | high | Decision can be reversed by editing one location | | medium | Reversal requires coordinated changes across 2-5 files | | low | Reversal requires migration, deprecation cycle, or schema change |
ADR promotion candidates = (impact=H) AND (reversibility=low OR medium).
Findings with incomplete-contract=Yes are also promoted regardless of documented? value, because the missing rule for future contributors is precisely what an ADR records (and a comment, by itself, cannot).
Other findings are recorded but not promoted (informational).
Skip this sub-step if --no-challenge is set.
Spawn critic-design via Task with the initial promotion candidate list. The agent challenges each candidate with:
ADR worth heuristic and incomplete-contract examples: see ${CLAUDE_SKILL_DIR}/references/decision-criteria.md (pass to critic-design alongside the candidate list).
For each candidate, critic-design returns one of:
| Verdict | Meaning |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| keep | ADR worth, file as standalone or merge with related candidates |
| downgrade | Not standalone ADR; absorb into a related ADR section or strengthen comments |
| drop | Not ADR-worthy; config/comment/test already covers it, cost > value, or the candidate is a bug (surface as bug-fix follow-up, do not document the wrong behavior) |
Record the challenge verdict alongside the initial ranking. The final candidate list = initial candidates marked keep + those marked downgrade (with target ADR), minus those marked drop.
When agent is unavailable or times out, fall back to initial ranking with a challenge_skipped: timeout note in the summary.
mkdir -p docs/audit
STAMP=$(date -u +%Y-%m-%d-%H%M%S) # UTC date + HHMMSS; same-day reruns never collide
REPORT="docs/audit/${STAMP}-adr-gaps.md"
Write the report following ${CLAUDE_SKILL_DIR}/templates/report-template.md, substituting placeholders (<YYYY-MM-DD>-<HHMMSS>, <source>:<line>, <summary>) from findings. Add a per-file summary line keep N / downgrade N / drop N. If --no-challenge was set, omit the Challenge and Final columns and use the initial ranking.
Print only the post-challenge keep candidates and offer to invoke /adr for each, or aggregate them into a single tracking issue via /issue. downgrade candidates are listed as comment-strengthening tasks (not ADRs). drop candidates are recorded in the report for traceability but not surfaced as follow-up.
docs/audit/<YYYY-MM-DD>-<HHMMSS>-adr-gaps.md/adr or tracking issue via /issue/adr after this skill produces the candidate list)/audit-adr-drift)scripts/audit-adr-scopes.py directly; this skill is single-repo by design)docs/audit/<YYYY-MM-DD>-<HHMMSS>-adr-gaps.mdtools
Internal helper for /think Step 11. Renders SOW.md + Spec.md as an integrated Astro view and returns a dev server URL.
development
Extract repository spec while detecting bugs, spec gaps, and consistency drift via dual-purpose documentation. OUTCOME.md-axis question-driven exploration with ephemeral output. Do NOT use for code review (use /audit or /polish), feature implementation (use /code), planning only (use /think), or single-bug fix (use /fix).
development
Scan ADR Decision sections against current code and report drift with modification direction and priority. Do NOT use for repos without ADRs (use audit-adr-gaps instead).
data-ai
Surface the current session's tentative reflection (realization / judgment / counterfactual) and optionally promote it to the durable knowledge store. Escape hatch for when Stop hook reflection extraction failed.