---
name: tidy-project
description: >-
  Use when the user explicitly invokes /tidy-project. Runs a read-only,
  three-phase audit of project structure for easier solo-dev maintenance.
  Identifies dead code, duplication, premature abstraction, over-nesting,
  over-coupling, vestigial framework scaffolding, stale markers, and
  docs/code drift. Produces a ranked execution plan persisted to
  `.agents/tidy/project/` — does not modify source files.
allowed-tools: Read Write Glob Grep TaskCreate TaskGet TaskUpdate TaskOutput TaskList Bash(scripts/collect-git-signals.sh:*) Bash(git log:*) Bash(git ls-files:*) Bash(git grep:*) Bash(git rev-parse:*) Bash(git rev-list:*) Bash(git diff:*)
---

# tidy-project Audit

A read-only, three-phase audit of project structure that produces a ranked, prioritized execution plan for reducing maintenance burden on a solo developer. All outputs are persisted to `.agents/tidy/project/` — no source files are modified.

## Activation

This skill activates ONLY when the user explicitly invokes it via the /tidy-project slash command. Do NOT auto-activate on natural-language requests such as "audit my repo," "review my codebase," "simplify my project," "clean up my project," or "what can I delete" — those phrasings must not trigger this skill.

### Output directory convention

Outputs go to `.agents/tidy/project/` at the repo root. If a project doesn't use that convention, substitute the output path globally in this SKILL.md workflow. The skill itself doesn't care which path is used; it only cares that all outputs land in one directory.

### Re-run behavior

If `.agents/tidy/project/` already contains files from a prior run, stop and ask the user before proceeding. Options to offer:

1. **Fresh run** — move the old directory to `.agents/tidy/project-archive/YYYYMMDD/` and start over.
2. **Resume** — pick up where the previous run left off (e.g. if Phase 1 completed but Phase 2 didn't, skip re-running Phase 1).
3. **Incremental update** — keep `01-inventory.md` if the user confirms the stack hasn't changed, but re-run Phase 2 findings against current code.

Never silently overwrite prior audit output.

---

## Hard Constraints

Every phase enforces these. Surface a violation if any subagent proposes a change that breaks them.

- **Preserve functionality.** Every proposed change must be behavior-preserving.
- **Preserve infrastructure.** Languages, frameworks, hosting targets, databases, and runtime environments are fixed — identified in Phase 1 and treated as given.
- **No dependency swaps** unless a dependency is demonstrably unused or trivially replaceable by ~10 lines of stdlib/builtin code.
- **No rewrites.** Only consolidations, deletions, flattenings, and renames.
- **No modification of source files.** Only files inside `.agents/tidy/project/` may be created.

---

## Gotchas

- **Concurrency cap.** Phase 2 caps area analysis at 5 concurrent subagents. With 6+ top-level areas, run in waves of 5 — do not skip areas to fit the cap.
- **Re-run detection.** A stale `.agents/tidy/project/01-*.md` from a prior run counts as "prior run files" — confirm freshness with the user before continuing or starting over.
- **Malformed subagent summary.** If a subagent writes a malformed summary (missing required fields), the orchestrator should treat it as FAIL and stop — do not silently retry or stall waiting for completion.
- **TP-10 date parse failures.** TP-10 stale-marker subagents pipe through `while read` after a `date_to_ts` call inside `set -e` — a date parse failure silently skips entries rather than aborting. If counts seem unexpectedly low, suspect this.

---

## Model & Effort Guidance

The orchestrator stays thin: it spawns subagents, relays their short summaries, and pauses for user input between phases. Sub-agents do all reading, writing, and synthesis. This keeps orchestrator context small on large repos and prevents mid-run compaction.

- **Orchestrator:** use a frontier reasoning model (e.g. Claude Opus 4.5, Gemini 2.5 Pro).
- **Subagents:** use a mid-tier model (e.g. Claude Sonnet 4.5, Gemini 2.5 Flash) at high effort for analysis, synthesis, ranking, and adversarial review; medium effort for docs drift comparison.
- **For TP-10 stale-marker enumeration and fan-in/fan-out counting within an Area Analyst,** a fast cheap model (e.g. Claude Haiku 4.5, Gemini Flash 2.5) is sufficient — these tasks are mechanical grep/count operations. The Area Analyst's reasoning effort should be reserved for TP-01 through TP-09 classification.
- **For smaller projects,** downgrading the orchestrator to mid-tier is reasonable.

## Subagent Return Contract

Every subagent spawned by this skill MUST end its reply with a Summary block under 150 words containing: output file path(s), key counts (findings, areas, batches), and a verdict (PASS / PASS WITH CORRECTIONS / FAIL, where applicable). Subagents MUST NOT restate the contents of files they wrote — those are on disk for the orchestrator and user to read on demand. The contract is enforced by every prompt in `references/adversarial-review-prompts.md`.

---

## Audit Workflow

Three phases. The orchestrator does no file reading or synthesis itself — every substantive step is a Task subagent. The orchestrator spawns agents, relays their ≤150-word summaries, and stops for user confirmation between phases.

All prompts referenced below live in `references/adversarial-review-prompts.md` and already include the required references and the return contract. The orchestrator does NOT need to load those references into its own context.

### Phase 1 — Inventory

1. **Collect git signals.** Run `scripts/collect-git-signals.sh <project-directory>` and save output to `.agents/tidy/project/01-git-signals.md`. If the project isn't a git repo, the script exits with code 2 — note this and tell the Inventory Builder to proceed without git signals.
2. **Build inventory (subagent).** Spawn an **Inventory Builder** subagent (model `sonnet`, effort `high`) using the "Inventory Builder" prompt. It writes `.agents/tidy/project/01-inventory.md` and returns a ≤150-word summary.
3. **Review in parallel.** Spawn both review subagents concurrently (independent, read-only):
   - **Docs Drift Reviewer** (model `sonnet`, effort `medium`) — writes `.agents/tidy/project/01-drift.md`.
   - **Inventory Reviewer** (model `sonnet`, effort `high`) — writes `.agents/tidy/project/01-inventory-review.md`.
4. **Reconcile.** Read only the reviewer summaries returned in the subagent replies. On PASS, proceed. On PASS WITH CORRECTIONS or FAIL, respawn the Inventory Builder with the reviewer's file path as input and instruct it to produce a revised `01-inventory.md`.
5. **Stop.** Show the user the Summary blocks from the Inventory Builder and Docs Drift Reviewer, plus the file paths (`01-inventory.md`, `01-drift.md`). Do not echo file contents — the user opens them if they want detail. Wait for confirmation before Phase 2.

### Phase 2 — Findings

1. **Parallel area analysis.** From the Inventory Builder's summary, identify the top-level areas. Spawn one **Area Analyst** subagent per area (model `sonnet`, effort `high`), up to 5 concurrent. Each writes `.agents/tidy/project/02-findings-{area}.md`, capped at the top 15 findings by score (the prompt enforces the cap and notes discards). If a subagent fails, log the error and continue. Relay only the ≤150-word summary each returns.
2. **Cross-cutting synthesis (subagent).** Spawn a **Cross-Cutting Synthesizer** subagent (model `sonnet`, effort `high`). It reads all `02-findings-*.md` files, writes `.agents/tidy/project/02-findings-cross-cutting.md`, and returns a summary. Pass it the list of areas (including any that failed in step 1) so it can note missing coverage.
3. **Adversarial review.** Spawn a **Findings Reviewer** subagent (model `sonnet`, effort `high`). It writes `.agents/tidy/project/02-findings-review.md` and returns a summary with a verdict and actionable-percentage estimate.
4. **Rank (subagent).** Spawn a **Ranking Reconciler** subagent (model `sonnet`, effort `high`). It reads all per-area findings, the cross-cutting synthesis, and the reviewer file; applies KEEP/REVISE/DROP decisions; groups dependency-linked findings; scores per the ranking formula; and writes `.agents/tidy/project/02-findings-ranked.md`. It returns a summary.
5. **Stop.** Show the Ranking Reconciler's summary and the `02-findings-ranked.md` path. Wait for confirmation before Phase 3.

### Phase 3 — Execution Plan

1. **Sequence (subagent).** Spawn an **Execution Plan Architect** subagent (model `sonnet`, effort `high`). It reads `02-findings-ranked.md`, writes `.agents/tidy/project/03-execution-plan.md`, and returns a summary.
2. **Adversarial review.** Spawn an **Execution Plan Reviewer** subagent (model `sonnet`, effort `high`). It writes `.agents/tidy/project/03-execution-plan-review.md` and returns a summary.
3. **Reconcile.** On PASS WITH CORRECTIONS or FAIL, respawn the Execution Plan Architect with the review file as input and instruct it to produce a revised plan.
4. **Stop.** Show the Architect's final summary and the `03-execution-plan.md` path. Do not apply any changes.

---

## Output Files

All written to `.agents/tidy/project/` at the repo root:

| File | Phase | Purpose |
|------|-------|---------|
| `01-git-signals.md` | 1 | Last-touched dates, churn hotspots, stale files, stale markers |
| `01-inventory.md` | 1 | Stack, framework conventions, directory tree, entry points, config |
| `01-inventory-review.md` | 1 | Adversarial review of inventory |
| `01-drift.md` | 1 | Docs/code drift findings |
| `02-findings-{area}.md` | 2 | Per-area findings (one file per top-level area) |
| `02-findings-cross-cutting.md` | 2 | Cross-area duplicates, conflicts, vocabulary |
| `02-findings-review.md` | 2 | Adversarial review of all findings |
| `02-findings-ranked.md` | 2 | Merged, ranked list of surviving findings |
| `03-execution-plan.md` | 3 | Sequenced batches with verification checklists |
| `03-execution-plan-review.md` | 3 | Adversarial review of execution plan |

---

## When to Load Reference Files

The orchestrator loads only `references/adversarial-review-prompts.md`. Each subagent prompt in that file lists the specific references that subagent must read — no other loading is needed.

---

## Solo-Dev Lens

Every subagent applies this lens. Full rubric — the four tests (re-derivation, earning-its-keep, deletion, grep) and the biases they imply (flat over nested, inline over abstracted, co-located over shared, deleted over kept) — in `references/solo-dev-lens.md`. The orchestrator does NOT load it; each subagent prompt instructs the subagent to read it.

---

## Scope Rules

**Review:** everything under the project root — directory structure, file organization, entry points, config, build pipeline, dependency manifests, documentation.

**Skip:** anything required by frameworks or toolchains identified in Phase 1 (e.g. Astro's `src/pages/`, Next.js's `app/`, Django's `settings.py`, `.github/workflows/`, `Dockerfile`, `package.json`, `tsconfig.json`, `Makefile`). Phase 1 identifies these; Phase 2 subagents treat them as off-limits.

**Always skip (noise directories):** `node_modules/`, `vendor/`, `.git/`, `dist/`, `build/`, `out/`, `__pycache__/`, `.venv/`, `venv/`, `.next/`, `.nuxt/`, `.astro/`, `target/`, `coverage/`, `.cache/`, `.parcel-cache/`, `.turbo/`, generated code, lockfiles, and binary assets.

**Test files** are reviewed at the structural level (existence, organization, dead tests). Within-test code-smell review is `tidy-code` (which applies a light-touch ruleset to tests — see its SKILL.md Scope Rules).

**Do not modify any files outside `.agents/tidy/project/`.** This skill produces recommendations only. Execution is the user's decision and happens outside the skill.
