# Which Cleanup

> Route a completed change to proportionate cleanup and guard skills. Use after editing or committing code to inspect only the changed scope, choose warranted closeout guides, and return on-demand guide/tool paths for direct or fresh-sub-agent execution. Ambient installation is explicit and optional.

- Skill: `khurrummahmood/which-cleanup` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds@latest add khurrummahmood/which-cleanup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/khurrummahmood/which-cleanup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: KhurrumMahmood (https://skillmd.com/u/khurrummahmood)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/khurrummahmood/which-cleanup

---


# /which-cleanup

Route a completed change to a small, proportionate closeout roster. This is the
third default router alongside `/which-shape` and `/which-skill`:

- `/which-shape` chooses the operating loop;
- `/which-skill` chooses a task skill;
- `/which-cleanup` chooses post-change checks and guards.

Do not execute the recommended skills. Return exact on-demand guide and tool
paths so the calling agent can load only what it needs. For non-trivial
closeout, prefer a fresh non-context sub-agent per independent read-only lens;
keep mutations serial.

## Run

From a Codex project installation:

```bash
cd .agents/skills/which-cleanup
python3 scripts/route.py <scope args> --project-root <host-root> --json
```

Supported scopes:

```text
<path> [<path> ...]
--staged
--changed-from <ref>
--commit <sha>
--range <a..b>
```

With no scope flag, inspect the working-tree, staged, and untracked file lists.
The portable router requires only Python’s standard library and Git when a diff
scope is used.

`--scope-mode auto` preserves each scanner's current behavior. For a Git
selector, `--scope-mode changed-files` analyzes each selected file in full;
`--scope-mode diff-lines` lets line-local scanners report only findings that
intersect new-side changed lines. Explicit paths use `paths`. Project-wide
analysis is intentionally delegated to project-capable scanners rather than
silently broadening this change-bounded router.

## Interpret the result

Honor these fields:

- `scope_band`: `trivial`, `small`, `medium`, or `large`, based on changed-file
  count. It controls roster width, not correctness or risk by itself.
- `resolved_paths`: the exact bounded paths considered.
- `scan_request`: the reusable selector, content basis, path/change facts, and
  changed-line ranges. Pass this exact object to selected scanners; do not
  resolve the Git selector again per recommendation.
- `recommendations[]`: skill, reason, primary on-demand `handoff` with the
  shared source-inventory path and manifest-backed language/fact/outcome
  capability row, and an `optional_install` result used only when the user
  requests ambient installation. The command is present only for closures with
  passed selected-install evidence; unvalidated closures are explicit.
- `recommendations[].scan`: requested/effective mode, diff semantics, and an
  explicit `ready`, `adapted`, `widened`, `degraded`, `unsupported`, `unsafe`,
  or `unavailable` status. `widened` preserves file/multi-site/project
  obligations that cannot truthfully be hunk-clipped. Do not run an unsupported
  or unsafe mode.
- `source`: the canonical repository and conventional skill/tool roots.
- `limitations`: what portable mode deliberately does not infer.

The universal closeout floor is test-obligation drift, comment drift, and
regression prevention. Wider changes additionally surface duplication,
omnibus-module, and incomplete-sweep checks. This is a conservative router,
not proof that every recommendation applies.

## Handoff

For each relevant recommendation:

1. Skip it explicitly if it is irrelevant to the actual change.
2. For a tiny check, read only its `handoff.guides` paths directly.
3. For a non-trivial independent check, create a fresh non-context sub-agent
   with the bounded `scan_request`, recommendation `scan` contract, reason, and
   returned guide/tool paths. The adapter says whether changed paths seed wider
   analysis or the request triggers a project scan; do not hunk-clip those
   findings.
4. Follow that skill’s own support and runtime claims; a location is not a
   claim that the tooling is language-neutral or independently installable.

When a selected producer returns a normalized finding artifact, apply committed
human review memory after detection and scope attribution:

```bash
cd .agents/skills/which-cleanup
python3 scripts/reviewed_findings.py \
  --decisions <project-root>/.engineering/quality/finding-decisions.jsonl \
  filter --artifact <normalized-findings.json> --output <actionable.json>
```

The canonical ledger is `.engineering/quality/finding-decisions.jsonl` in the
host project. An unchanged `false-positive`, `accepted-debt`, or
`intentional-exception` decision is hidden from the default actionable list but
remains counted; add `--show-reviewed` to inspect it. Changed evidence, changed
subject identity, incompatible fingerprint semantics, malformed decision data,
and recurrence after `fixed` all remain visible. Record a judgment only after
human review:

```bash
python3 scripts/reviewed_findings.py \
  --decisions <project-root>/.engineering/quality/finding-decisions.jsonl \
  record --artifact <normalized-findings.json> --subject <stable-subject> \
  --disposition false-positive --rationale <why> --reviewer <identity> \
  --source-scan <scan-id>
```

The decision ledger stores hashes and bounded identity/location fields, never
the raw evidence or full source body. Failures, incomplete/unsupported results,
unlocated findings, and file/project obligations cannot be dismissed through
this line-finding mechanism.

Use `optional_install` only when the user explicitly chooses ambient
installation.

Skip irrelevant recommendations explicitly. Keep mutations serial even when
multiple read-only checks can run independently.

## Boundaries

- Advisory only; never edits production files or runs the selected skills.
- Does not load all skill bodies or a repository-wide execution runtime.
- Does not promise subsystem-specific routing without a separately installed
  project profile or task skill.
- The source checkout retains richer historical closeout scripts for its own
  development, but they are not part of this portable default path.
- The thin library bootstrap only materializes the source outside discovery;
  it is not a dispatcher, workflow coordinator, package manager, or trust
  layer.

## Failure handling

- No changed paths: report no recommendation and stop successfully.
- Invalid or conflicting scope flags: surface the usage error.
- Git unavailable or an invalid/empty diff scope: return a structured
  resolution failure; ask for explicit in-project paths rather than scanning
  or silently broadening to the working tree.
- Recommended skill unavailable or unsupported: report the source location and
  limitation; do not invent or inline its behavior.

## Files

```text
.claude/skills/which-cleanup/
├── SKILL.md
└── scripts/
    ├── route.py          # portable stdlib-only installed router
    ├── scan_request.py   # paths, Git changes, and new-side line ranges
    ├── scope_modes.py    # per-scanner effective-mode projection
    ├── finding_envelope.py # normalized artifact + shared scope adapters
    └── reviewed_findings.py # append-only review memory + fail-open filter
```

