/repo-doctor
What it does
Reads the current repo and answers the question prose AGENTS.md doesn't cheaply answer per session: what's missing for AI-first work here? Output is a Markdown report scored across ~15 dimensions, with a concrete fix action per gap (often "invoke /X").
Read-only. Modifies nothing. The skill is an audit, not a bootstrap.
This skill complements three existing ones with clean differentiation:
| Skill | Question it answers | |-------|---------------------| | /init-repo | "Set this fresh repo up." (writes files) | | /stack-check | "What I have — is it stale?" (freshness audit) | | /repo-doctor | "What I don't have — what's missing?" (completeness audit) | | /security-review | "Is this diff safe to commit?" (orthogonal — code-level scan) |
When to invoke
- Inheriting an existing repo (legacy or new-to-you) and wondering
what's missing for AI-first development.
- After
/init-reporan, to see what else the bootstrap didn't
cover.
- Periodically (every few months) to catch drift.
- When the
skill-cheatsheetSessionStart hook suggests a checkup. - Before pitching a "make this repo agent-ready" piece of work to a
client — output is a ready-made list of concrete improvements.
Do NOT invoke for:
- Day-to-day "is this stale" checks — that's
/stack-check. - Security audit of changes — that's
/security-review. - One-shot setup — that's
/init-repo.
Output format
# Repo Doctor — <repo-name> — <YYYY-MM-DD>
## Summary
✅ 8 pass · ⚠️ 4 attention · ❌ 3 missing · **Score: 67/100**
## Foundation (loaded every session)
| Check | Status | Fix |
|---|---|---|
| AGENTS.md (root) | ✅ 4.2 KiB | — |
| CLAUDE.md (one-line `@AGENTS.md` import) | ✅ present | — |
| Per-dir AGENTS.md | ⚠️ 3 source dirs >500 LOC missing | drop `templates/AGENTS.md.example` into `src/billing/`, `src/auth/`, `src/api/` |
## Why (load-bearing decisions)
| Check | Status | Fix |
|---|---|---|
| ADRs (docs/adr/) | ❌ directory absent | next load-bearing decision → invoke `/adr-new` |
| Session logs (docs/sessions/) | ⚠️ last entry 47 days old | end of next substantial session → `/session-log` |
## What (domain + structure)
| Check | Status | Fix |
|---|---|---|
| GLOSSARY.md | ❌ missing | invoke `/glossary-init` (auto-surfaces candidates) |
| architecture.yml | ❌ missing | invoke `/arch-map` |
## In-code discoverability
| Check | Status | Fix |
|---|---|---|
| AIDEV anchors | 12 anchors / 4823 LOC = 2.5/KLOC | typical (target 1–5/KLOC) |
| Overdue anchors | ⚠️ 2 past deadline | see `/stack-check` for detail |
## Engineering hygiene
| Check | Status | Fix |
|---|---|---|
| Tests present | ✅ 28 test files | — |
| Test/source LOC ratio | ⚠️ 0.18 (target 0.5–1.0) | `src/billing` largest, fewest tests — add coverage there first |
| Structured logging | ❌ `print(` 14×, no structured logger detected | invoke `/log-structured` |
| .gitignore (claude-leverage state) | ✅ present | — |
| README quickstart | ✅ present | — |
| Language manifest | ✅ pyproject.toml | — |
## Sync (code ↔ docs drift)
| Check | Status | Fix |
|---|---|---|
| `architecture.yml` ↔ disk | ⚠️ 2 drifts: `public_surface: [LegacyClient]` not in code; `src/old/` orphan (on disk, not in YAML) | invoke `/arch-map` to refresh |
| `GLOSSARY.md` ↔ code | ⚠️ term `Lead` no longer ref'd in code (last seen 4 months ago) | edit `GLOSSARY.md` or `/glossary-init --add` |
| Per-dir `AGENTS.md` staleness | ✅ all in sync | — |
| `CHANGELOG` ↔ version | ❌ `plugin.json` says 1.6.0, `CHANGELOG` top is 1.5.0 | add a `## [1.6.0]` entry to `CHANGELOG.md` |
| `README` slash-refs ↔ skills | ✅ all 13 slash commands resolve | — |
## Recommended next 3 actions
1. **`/arch-map`** — biggest unblock for refactor proposals; also fixes
sync drift on `public_surface: [LegacyClient]`; <5 min
2. **`/glossary-init`** — `Account` appears in 12 files; agent likely
hallucinating meaning
3. Add a `## [1.6.0]` entry to `CHANGELOG.md` to close the
version-drift gap
Dimensions
Foundation (3 checks — loaded every session, agent-facing)
AGENTS.md(root) —test -f AGENTS.md. Evaluate the size bands
largest-first (a 40 KiB file is a fail, not a warn):
- ❌ if missing.
- ❌ if size > 32 KiB — Codex silently drops content beyond
project_doc.max_bytes (32768), so part of the file is invisible to Codex agents. This is data loss, not a style nit.
- ⚠️ if size > 8 KiB — lean target exceeded; extract topic depth to
docs/ behind a when-to-read link. See ADR 0009.
- ✅ otherwise. Report size in KiB.
CLAUDE.md(root) —test -f CLAUDE.md.- ❌ if missing.
- ⚠️ if exists but doesn't contain
@AGENTS.md(i.e., diverges
from canonical guidance — split surface to maintain).
- ✅ if exists with
@AGENTS.mdimport.
- Per-directory
AGENTS.md— for each top-level source dir
(heuristic: has files matching .py|.ts|.tsx|.js|.jsx|.go|.rs|.java|.rb|.php|.cs|.kt|*.swift) compute LOC (wc -l aggregated). For each with > 500 LOC and no AGENTS.md at that dir root, count it.
- ✅ if 0 such dirs.
- ⚠️ if 1–3.
- ❌ if ≥4 (the per-module conventions story is broken at scale).
- Report names of the offending dirs (top 5).
Why (2 checks — load-bearing rationale)
- ADRs —
ls docs/adr/ 2>/dev/null | grep -E '^[0-9]{4}-.*\.md$'. - ❌ if
docs/adr/absent OR 0 numbered ADR files. - ⚠️ if 1–2 (suspiciously few for any real project).
- ✅ if ≥3.
- Report count.
- Session logs —
ls docs/sessions/*.md 2>/dev/nulland parse
the date from filename (YYYY-MM-DD-topic.md) or mtime fallback.
- ❌ if
docs/sessions/absent OR 0 logs. - ⚠️ if most recent log > 60 days old.
- ✅ if most recent ≤ 60 days.
- Report age of newest log.
What (2 checks — v1.5.0 additions)
GLOSSARY.md—test -f GLOSSARY.md.- ❌ if missing.
- ⚠️ if exists but >30% of entries are
<TODO>placeholders
(parse H2 sections, count those whose body contains the literal <TODO>).
- ✅ otherwise. Report entry count.
architecture.yml—test -f architecture.yml.- ❌ if missing.
- ⚠️ if exists but >30% of modules have
<TODO>placeholders
for role or stability.
- ✅ otherwise. Report module count.
In-code discoverability (2 checks)
- AIDEV anchor density —
grep -rE 'AIDEV-(NOTE|TODO|QUESTION)'
across tracked files (skip bench archive, vendor, node_modules, __pycache__, .git, dist, build). Count matches. Divide by total tracked code LOC (git ls-files filtered to code extensions → wc -l). Express as anchors-per-KLOC. Bands use half-open intervals ([a, b)) so every value falls in exactly one band:
- ❌ if density
< 0.3/KLOCAND total LOC> 1000(the repo is
big enough that the absence is signal).
- ⚠️ if density
[0.3, 1.0)/KLOC(sparse for an AI-first repo). - ✅ if density
[1.0, 10.0]/KLOC(typical). - ⚠️ if density
> 10/KLOC(anchor noise — clutter dilutes
load-bearing ones).
- Overdue / due-soon anchors — borrowed from
/stack-check's
anchor walk (intentional overlap; /stack-check provides the full actionable detail, this dimension just surfaces the count in the completeness report). Parse AIDEV-(TODO|QUESTION)(by: YYYY-MM-DD) and compare to today.
- ✅ if 0 overdue AND 0 due-soon.
- ⚠️ if ≥1 due-soon (next 14 days) but 0 overdue.
- ❌ if ≥1 overdue. Report top 3 with
file:lineand days
overdue; remind to run /stack-check for the rest.
Engineering hygiene (6 checks)
- Tests present — exists
tests/dir OR ≥1 file matching
**/test_*.{py}, **/*_test.{go,py}, **/*.test.{ts,tsx,js,jsx}, **/*.spec.{ts,tsx,js,jsx}, **/*Test.{java,kt}, etc.
- ❌ if 0 test files found.
- ⚠️ if 1–4 test files for repos with > 1000 LOC.
- ✅ otherwise. Report count.
- Test-to-source LOC ratio —