Structural health review of a repository — architecture and coupling, dependency risk, and drift between living docs/schema/config and the code. Run it at a milestone, after a large refactor or a big merge, when git churn is concentrated in a few files, when the user says the code is hard to change or keeps breaking in the same place, or as the first review on a repo that has never been reviewed (cold start — this is the cheapest profile: it needs only the repo, no running app and no diff). D...
Scanned 9/2/2026
Install to Claude Code
npx -y skills add mxrsv/agents-skills --skill review-health --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Review Health?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/mxrsv-review-health)More formats (shields.io, HTML) on the badges page.
---
name: review-health
description: Structural health review of a repository — architecture and coupling, dependency risk, and drift between living docs/schema/config and the code. Run it at a milestone, after a large refactor or a big merge, when git churn is concentrated in a few files, when the user says the code is hard to change or keeps breaking in the same place, or as the first review on a repo that has never been reviewed (cold start — this is the cheapest profile: it needs only the repo, no running app and no diff). Do NOT run it to review a specific change or diff (use /review-change), to review UX, user flow or runtime behavior (use /review-experience), or to decide whether to ship (use /review-release).
---
# /review-health
> **Harness note.** Skill names are written `/name` (Claude Code slash form); in Codex invoke the same skill as `$name`. Sub-agent dispatch is shown as Claude Code's `Agent({ subagent_type: "general-purpose", … })` — in Codex spawn a sub-agent with the same prompt, or apply the contracts inline, in sequence, when sub-agents are unavailable.
Reviews **the repo as it stands** — not a diff, not a running app.
| Reviewer | Evidence source | Looks for |
| --- | --- | --- |
| `architecture` | code tree · git churn, blame, hotspots | coupling, boundary violations, duplication, dead code |
| `deps` | lockfile · the stack's own audit tool · bundle size | CVEs, version skew, license, bloat |
| `contracts` | living docs + anchors · schema · config · build assumptions ↔ code | drift |
Three genuinely independent evidence sources. They never read the same thing twice, so fanning out is a real saving here — unlike `/review-change`, where all three reviewers share one diff.
**Cold start.** A repo that has never been reviewed starts here. This profile needs nothing but the repo — no dev server, no credentials, no base commit. Its output (churn ranking + drift) is what tells you where to point `/review-change` and `/review-experience` next. `/review-release` is meaningless until at least two profiles have run.
## 1. Collect the manifest — parent, once
```bash
git rev-parse HEAD # head_sha
git status --porcelain # THE manifest
git status --porcelain=v1 | shasum -a 1 | awk '{print $1}' # tree_digest
LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | head -c 6 # run_id
date +%Y-%m-%dT%H:%M:%S%:z # reviewed_at
```
Use `git status --porcelain`, **never `git diff`**. `git diff` is blind to untracked files, and untracked files are executable behavior — a repo can carry two dozen untracked skill directories while `git diff` reports nothing.
`dirty` is `true` when the porcelain output is non-empty.
## 2. Read the three contracts
- [reviewers/architecture.md](reviewers/architecture.md)
- [reviewers/deps.md](reviewers/deps.md)
- [reviewers/contracts.md](reviewers/contracts.md)
They are supporting files, not subagent definitions — no harness loads them automatically (Claude Code discovers agents only from `agents/*.md`, Codex from `~/.codex/agents/*.toml`), so you must read each contract and **paste its full text into the dispatched prompt**.
## 3. Decide execution mode — not coverage
Two separate variables. Do not mix them.
| Variable | Decided by | Floor |
| --- | --- | --- |
| Which contracts apply | risk | **always all three** — the sources are disjoint, so all three are always relevant |
| Subagent or inline | cost | 0 subagents is legal |
Coverage is fixed at three for this profile. A contract that finds nothing to read returns `blocked` — that is the *reviewer's* verdict, not permission for you to drop it. `skipped` should essentially never appear in a health report.
**Default: three subagents in parallel.** Go inline (apply the contracts yourself, in sequence) only for a repo small enough that the fan-out costs more than it saves — roughly under 30 tracked files with no dependency manifest. Cap for any `/review-*` command is 4 subagents; this one uses 3.
## 4. Dispatch — all three calls in ONE message
Three `Agent` calls in a single message run in parallel. Sent one per message, they serialize and you lose the whole point.
```
Agent({ subagent_type: "general-purpose",
name: "rev-architecture",
model: "opus",
prompt: <full text of reviewers/architecture.md> + OBJECTIVE + SCOPE + MANIFEST })
Agent({ subagent_type: "general-purpose",
name: "rev-deps",
model: "haiku",
prompt: <full text of reviewers/deps.md> + OBJECTIVE + SCOPE + MANIFEST })
Agent({ subagent_type: "general-purpose",
name: "rev-contracts",
model: "sonnet",
prompt: <full text of reviewers/contracts.md> + OBJECTIVE + SCOPE + MANIFEST })
```
Same `subagent_type`, different `name`, different `prompt`, different `model`. The contract carries the review logic; the agent type carries nothing. `name` is what lets you tell three concurrent runs apart. Set `model` per reviewer — `deps` is mechanical (cheap model), `architecture` is judgment-heavy (strong model).
The tail appended to every prompt:
```
OBJECTIVE: health review of <repo> at <head_sha><, dirty> — <one line on why it is being reviewed now>
SCOPE: repo root <absolute path>. source_kind=working-tree.
MANIFEST: <verbatim `git status --porcelain` output, or "clean working tree">
` ?` entries are untracked and invisible to git history — treat them as churn-unknown.
```
### What the parent does NOT do
**Do not pre-collect evidence.** Do not read the code tree, run the audit tool, or run the docs scripts and paste the results into the prompts. That defeats the reason for using subagents: your own context fills up, the same evidence is duplicated three times, and a reviewer can no longer follow a thread out of whatever bundle you happened to assemble. You pass objective + scope + manifest. Nothing else.
**Do not let subagents write files.** Three writers racing on `docs/review/*.md` produce conflicts and inconsistent format. They return findings as text; you write once.
## 5. Merge and write ONE report
Format, header fields, finding schema, domain list, budget and freshness rules all live in `~/.claude/templates/review-report.md`. Follow it; do not restate it here and do not invent fields.
Fixed for this profile:
```
path: docs/review/<YYYY-MM-DD>-health-worktree-<run_id>.md
profile: health
scope: worktree
source_kind: working-tree
head_sha: <from step 1>
dirty: <from step 1>
tree_digest: <from step 1>
deploy_rev: null
```
Merging:
- Dedupe across reviewers — keep the version with the stronger evidence, drop the restatement. Budget stays per reviewer; three reviewers at 3 findings each is 9, not 3.
- Domain prefixes are pre-assigned so parallel reviewers cannot drift the key space: `architecture` → `arch/`, `deps` → `deps/`, `contracts` → `docs/`.
- The coverage table lists **all three** reviewers with `ran` / `blocked` / `skipped` and a reason. Omitting a reviewer from that table is an error, not a shortcut.
- A reviewer that returned `blocked` still gets its row, with the reason it gave verbatim.
## 6. Report back
Give the user: the report path, the coverage line in one sentence, and the blockers plus the highest-severity findings. Do not paste the whole report back.
Findings live in the report and nowhere else. Anything the user decides to act on, they move by hand into a living doc (`docs/CONTEXT.md`, `docs/ARCHITECTURE.md`) or into an issue (`gh issue create`). There is no register and no auto-filing.
## Hard rules
- The parent writes the report. Reviewers never do.
- `git status --porcelain` for the manifest and the digest — never `git diff`.
- All three dispatch calls in one message.
- No finding without evidence. `blocked` with a reason beats a plausible guess.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!