- name
- cleanup
- description
- Assess the project to reorganize or deprecate unused/outdated files. Joins each candidate against per-candidate dependency evidence, blocks mutation per class on the evidence that class actually needs, and keeps assessment running when indexing is unavailable.
- allowed-tools
- Bash, Read, Grep, Glob
- triggers
- ["cleanup this project","reorganize the codebase","remove outdated files","deprecate unused code","git cleanup","archive artifacts","move artifacts to storage"]
- metadata
- {"short-description":"Dependency-informed, fail-closed codebase cleanup"}
- provides
- ["cleanup"]
- composes
- ["ingest-code","task-monitor","project-watchdog","agentic-evals"]
- complies
- ["best-practices-skills","best-practices-python","best-practices-report","best-practices-security"]
- disciplines
- ["developer-tooling","observability-operations"]
# Cleanup Skill
This skill performs a deep assessment of the codebase to identify technical debt, unused files, and outdated documentation, then performs cleanup operations with confirmation.
## Key Features
- **Artifact review**: Detects binary/media files (`.wav`, `.mp4`, `.pt`, `.ckpt`, `.parquet`, etc.) but keeps root-level candidates review-only because they may be runtime inputs
- **Root stray detection**: Flags untracked directories at project root that don't belong (e.g. `personaplex/`, `data_horus/`)
- **Human-authorized deprecated move**: When the human explicitly says to move
root strays or artifacts into a deprecated folder and not delete them, perform
only a path-scoped `mv` into `deprecated/cleanup-<date>/...`, write a receipt
with source, destination, size, and SHA-256, read back old-path absence and
new-path presence, and commit only that deprecated path plus the receipt.
This is not `--execute`; it is an owner-approved preservation move.
- **Junk file cleanup**: Removes logs, temp files, cache dirs
- **Unused-file candidate detection**: Uses lexical absence only to nominate
review candidates; it never treats that signal as removal proof
- **Per-candidate dependency evidence**: Joins each candidate against
`.cleanup-evidence.json` and emits a verdict per file. Aggregate ingest
counters are reported with their proof limits, never as per-file safety
- **Per-class mutation authority**: Each mutation class carries the evidence it
actually needs; no class inherits authority from an unrelated index
- **Resumable phase receipt**: `--plan`, `--execute`, and the default summary
write phase states for local dependency analysis, Memory indexing,
assessment, and mutation. `--dry-run` returns the same receipt inline under
`phase_receipt` instead of writing it; `--worktree-audit` produces its own
audit artifacts and no phase receipt
- **Doc staleness**: Flags docs with TODO/FIXME or >365 days without changes
- **Script scanability**: Flags tracked script-like files that are hard for a
human or agent to scan because they lack useful file-purpose, usage,
side-effect, function, or class documentation. This is readability debt, not
unused-code evidence.
- **Public-readiness/security cleanup**: `--public-readiness` preserves
gitleaks and GitHub settings blockers for maintainer triage without changing
repository visibility or allowlists automatically.
- **Quality-gate cleanup**: `--quality-gate` runs selected project-native
parse, lint, type, and test gates when available and reports missing or
unestablished gates as scoped blockers.
- **Memory-index cleanup**: `--memory-index` invokes `$ingest-code --treesitter`
and writes a local searchability/offline-artifact receipt for project agents.
- **Pre-mutation receipt gate** (#1125): before any memory-mutating lane (`--memory-index`, future `prompt_receipt_refresh`) executes for real, cleanup consumes the `$ops-arango` backup receipt (`/mnt/storage12tb/backups/arangodb/latest_backup_receipt.json`, threshold 48h) and the owning monitor's health receipt (`monitor-sparta` `state.json`, threshold 24h). Check-then-skip: fresh receipts are cited as-is in the phase receipt; cleanup never runs `arangodump` or re-implements monitor checks. Stale/failing evidence fails the lane closed (exit 0, no ingest invocation) with blockers `memory_backup_stale`, `memory_health_stale`, or `memory_health_failing`, each naming the exact producer command to re-run. Overrides: `CLEANUP_ARANGO_BACKUP_RECEIPT`, `CLEANUP_MONITOR_HEALTH_RECEIPT`, `CLEANUP_BACKUP_MAX_AGE_HOURS`, `CLEANUP_HEALTH_MAX_AGE_HOURS`, `CLEANUP_HEALTH_ALLOWED_FAILING`.
- **Evidence-first Markdown report**: `--plan` writes a prose-first cleanup
report that follows `$best-practices-report`: summary, scope,
source-of-truth inventory, finding index, outstanding/unknowns,
plan-ready next actions, and non-claims. It must not present cleanup counts as
dashboard health or readiness claims.
- **Worktree triage**: Classifies current dirty git entries into
commit/archive/review buckets, and `--registered-worktree-audit` enumerates
every `git worktree list` registration for rescue/prune planning
- **Dependency-safe quarantine**: Treats untracked source/config files as
possible runtime dependencies of tracked code until import/readiness checks
prove otherwise
- **Nightly-readiness discipline**: Requires each project cleanup to preserve
an easy sanity command, browser-oracle registry, best-practices receipts for
changed relevant files, and a clean task commit/push boundary
- **Clean worktree governance**: Allows a secondary clean worktree only for
commit isolation, with disclosure, live-repo proof, and later removal
- **Reviewer-blocker receipts**: Treats unavailable `$ask`/WebGPT/Surf lanes as
external blockers with request, receipt, and lock-owner evidence
- **Degraded marker honesty**: A `.ingest-code.json` that claims completion
while scanning zero files, disabling the code index, or storing zero
Tree-sitter symbols is degraded aggregate context, not complete indexing
- **Project-watchdog coordination**: Reads `$project-watchdog`
`registry/projects.json` and `registry/state.json` as advisory state before
planning, auditing, or executing. Cleanup never ticks the watchdog, leases an
issue, relabels an issue, closes an issue, or treats open GitHub issues as
cleanup candidates.
- **Agentic eval gate**: For skill cleanup, runs the target skill's
`fixtures/agentic_eval.json` through `$agentic-evals`. Cleanup records the
eval report, requires `readiness: READY`, and blocks the cleanup state when
the fixture is missing or non-READY.
## Evidence Model
Indexing failures never stop non-mutating work. `--dry-run`, `--plan`, and
`--worktree-audit` always run. `--plan`, `--execute`, and the default summary
write a phase receipt with five independent states (`--dry-run` returns it
inline under `phase_receipt`):
```
local_dependency_analysis: complete | incomplete | unavailable
memory_indexing: complete | blocked | unknown
assessment: complete
agentic_evaluation: complete | blocked | not_applicable
mutation: allowed_limited | no_authorized_mutations
```
A Memory outage blocks `memory_indexing` only. It must not block assessment,
planning, or the worktree audit.
Each mutation class carries its own evidence requirement:
| Class | Evidence required | Current status |
|---|---|---|
| `junk_untracked_removal` | untracked status + junk pattern + no literal reference from a tracked file | allowed when candidates clear provenance |
| `tracked_file_mutation` | per-candidate evidence from `.cleanup-evidence.json` + project-native before/after readiness proof | blocked until both are present |
| `script_scanability_repair` | explicit readability cleanup request + parse/compile + script `--help` or narrow sanity proof | non-mutating assessment by default; repair as separate slice |
| `public_readiness_security_triage` | explicit public-readiness request + gitleaks history receipt + per-finding triage/allowlist + narrowed working-dir scan + maintainer GitHub settings inventory | non-mutating assessment by default; blocks public-release claims until receipts exist |
| `quality_gate_validation` | explicit quality-gate request + scoped project-native parse/lint/type/test receipts | non-mutating assessment by default; blocks proof claims until selected gates run |
| `memory_index_refresh` | explicit memory-index request + ingest-code receipt + `.ingest-code.json` + local artifact paths | non-cleanup mutation; indexes for project-agent recall/search |
| `registered_worktree_rescue_prune` | explicit rescue/prune request + dirty secondary audit + active-process exclusion + pushed rescue branch receipt + clean status proof before remove | non-mutating audit by default; blocks prune/remove until rescue proof exists |
| `agentic_evaluation` | target skill `fixtures/agentic_eval.json` run through `$agentic-evals` with `readiness: READY` | complete, blocked, or not_applicable |
| `root_stray_mutation` | human owner decision + path-scoped deprecated move receipt | review-only until explicitly authorized |
| `artifact_archive` | human owner decision + path-scoped deprecated move receipt | review-only until explicitly authorized |
Untracked junk removal does not require dependency edges: it only ever touches
paths git does not track. Requiring a repository-wide index for it costs a live
ingestion and proves nothing about the paths being removed.
### Exit codes
| Code | Meaning |
|---|---|
| `0` | The run completed and every decision was made on evidence. Zero actions is a success: nothing to clean, and withheld candidates, both exit `0`. |
| `2` | Cleanup could not evaluate the evidence it was given — a corrupt evidence artifact or marker, an artifact belonging to another repository, or a git state that yields no tracked files. |
| `1` | Unhandled error. |
Missing evidence is not an error. It blocks the mutation classes that need it,
is recorded in the phase receipt, and exits `0`. Automation should read
`mutation_classes` in the receipt rather than inferring intent from the exit
code alone.
`$ingest-code scan` writes `.cleanup-evidence.json` in Phase 0 before Memory writes, so a Memory outage yields
`local_dependency_analysis: complete` with `memory_indexing: blocked` rather than
losing the analysis. See `references/cleanup-evidence-contract.md` for the
`cleanup.evidence.v1` schema and per-candidate verdict semantics.
### Proof limits of the aggregate marker
`.ingest-code.json` holds scalar counters. It is reported for context and is
never per-file safety evidence. Every run states these limits explicitly:
- `coverage_proof=count_only` — a scanned-file count, not a path set. It can
pass while the wrong files were scanned.
- `freshness_proof=mtime_only` — filesystem mtime is unreliable after checkout,
copy, rebase, or clock change.
- `edge_scope=python_imports_only` — `$ingest-code` resolves edges from Python
static imports (`ingest_code.py:2992-3008`). For any other language an empty
reference set carries no information.
- `aggregate_only` — `edges_stored` is a storage count and says nothing about
any individual candidate.
- `zero_scan_is_degraded` — if the marker claims `completed: true` but
`files_scanned` is `0`, `code_index.enabled` is false, or Tree-sitter stores
no symbols, cleanup must report marker warnings and must not set
`memory_indexing: complete` from that marker.
- `verdict_counts_not_evidence_absence` — candidates with explicit verdicts
such as `entry_root`, `referenced`, or `outside_analysis_scope` have evidence
that blocks mutation. They must not be reported as "lacking evidence"; only
missing, stale, corrupt, failed, or out-of-scope records are unusable evidence.
## Workflow
1. **Assessment** (`--dry-run`): always runs, index or no index. Scans the
codebase for:
- Root-level artifacts and stray directories → review only
- Untracked "junk" files (logs, temp images, build artifacts) → per-path
provenance verdict; only cleared paths become removable
- Tracked files with no lexical references → non-mutating review candidates,
each joined against per-candidate dependency evidence
- Outdated documentation files
- Script scanability gaps → non-mutating readability candidates for
file-purpose, usage, side-effect, function, or class documentation
- Public-readiness blockers → non-mutating security/readiness candidates for
gitleaks history triage, noisy working-directory scans, and GitHub
visibility/security/reporting review
- Quality-gate blockers → non-mutating parse/lint/type/test candidates for
the selected cleanup slice
2. **Planning** (`--plan`): Generate a **Cleanup Report** markdown file that
complies with `$best-practices-report`: top summary, scope,
source-of-truth inventory, finding index, detailed evidence sections,
outstanding/broken/unknowns, plan-ready next actions, and non-claims. The
report shows phase states, proof limits, marker warnings, and one verdict row
per candidate, including script scanability repair rows.
3. **Worktree triage** (`--worktree-audit`): Generate JSON + Markdown ownership/risk
buckets for dirty files so agents do not blindly stage unrelated work.
4. **Registered worktree rescue audit** (`--registered-worktree-audit`):
Enumerate all worktree registrations, mark `/tmp`, detached, prunable,
active, dirty, and clean removal candidates, and emit rescue/prune commands.
5. **Repo-of-record declaration**: Identify the live project checkout, branch,
dirty inventory, and any secondary clean worktree used only for commit
isolation.
6. **Readiness baseline**: Resolve the project's `$browser-oracle` registry and
run the project's easy sanity command before moving source-like files.
7. **Project-watchdog coordination** (`$project-watchdog`): Read the shared
watchdog registry and state. If the current repo is registered and both the
global and project state are `active`, cleanup execution is blocked until
watchdog dispatch/routing state is coordinated or paused by an authorized
operator. This check is read-only; cleanup must not query or resolve GitHub
issues, acquire leases, or run watchdog ticks.
8. **Code evidence / searchability** (`$ingest-code`): Only required to unblock
tracked-file mutation, never to run assessment or untracked junk removal.
Run `--memory-index` to
invoke `bash ~/workspace/experiments/agent-skills/skills/ingest-code/run.sh scan "$PWD" --treesitter`,
refreshing `.ingest-code.json`, `.cleanup-evidence.json`, and code-symbol
JSONL artifacts where supported.
If this leaves a completed marker with zero scanned files or a disabled code
index, treat the marker as degraded and rely on `.cleanup-evidence.json` for
local dependency analysis only.
9. **Agentic eval gate** (`$agentic-evals`): When cleanup is invoked from a
skill directory, run `fixtures/agentic_eval.json` through `$agentic-evals`
before reporting completion. A missing fixture, invalid report, non-zero
runner exit, or readiness other than `READY` is a blocked cleanup state.
Writing modes store the eval report under
`artifacts/cleanup/agentic-evals/<skill>.json`; `--dry-run` returns the same
gate data inline without writing the receipt file.
10. **Execution** (`--execute`): Perform authorized mutations with confirmation:
- Remove only untracked junk paths that cleared per-path provenance
(`--force` skips the prompt, not the provenance check)
- Keep root strays, artifacts, and tracked candidates review-only
- Log all actions to `local/CLEANUP_LOG.md` and the phase receipt
11. **Human-authorized deprecated move**: When the human explicitly authorizes
a preservation move such as "move to deprecated folder, do not delete",
perform a bounded manual `mv` slice rather than `--execute`.
Preconditions:
- Read the latest `--worktree-audit` or `--dry-run` receipt and name the
exact paths being moved.
- Exclude `.agents/`, `.codex/`, `.claude/`, `.worktrees/`, registered Git
worktrees, current cleanup outputs, runtime state, source/config/test
paths, and any evidence artifacts still needed for the active proof unless
the human names them explicitly.
- For source-like, config, service, test, or script paths, first run the
"Readiness Before Moving Source-Like Files" gate below. If that gate is not
available, do not move those paths.
- Create `deprecated/cleanup-<YYYYMMDD>/<class>/` inside the live repo unless
the human names a different destination.
- Use `mv --` only after checking the destination does not already exist.
Do not run `rm`, `git clean`, `git reset`, `git checkout --`,
`git worktree remove`, `git worktree prune`, or any delete/prune command.
- Write a receipt such as
`deprecated/cleanup-<YYYYMMDD>/MOVE_RECEIPT.tsv` with timestamp, source,
destination, byte size, and SHA-256.
- Read back the result with counts for `old_paths_absent`,
`new_files_present`, and `receipt_records`.
- Stage and commit only the moved deprecated paths and receipt. Do not stage
unrelated dirty worktree entries to make the repository look clean.
Non-claims: this move does not prove the whole worktree is clean, does not
authorize deletion, and does not prove unreviewed root strays are unused.
12. **Script scanability repair**: When the requested cleanup slice is explicitly
readability repair, add only non-behavioral documentation such as module
docstrings, usage notes, side-effect notes, and useful function/class
docstrings. Do not change script control flow, flags, imports, IO behavior,
network behavior, or destructive actions while doing this slice. Prove the
slice with parse/compile plus each touched script's `--help`, entrypoint
smoke, or narrow sanity command, then commit separately from deletion or
archive cleanup.
13. **Public-readiness/security triage**: For an explicit public-readiness
slice, run `--public-readiness`, preserve artifacts, triage gitleaks history
findings, narrow noisy working-directory scans, and require maintainer
review for GitHub visibility/security/reporting settings. See
`references/public-readiness-security.md`.
14. **Quality-gate validation**: For an explicit validation slice, run
`--quality-gate` and preserve the receipt. Missing configured tools,
unexecuted required gates, or failed gates remain blockers. See
`references/quality-gates.md`.
15. **Post-cleanup proof**: Rerun the same sanity command, the target skill's
`$agentic-evals` fixture, and relevant `best-practices-*` checks for changed
files, then commit/push only the coherent cleanup slice.
## How to Use
1. Trigger with "cleanup this project" or "archive artifacts".
2. Run `bash ~/workspace/experiments/agent-skills/skills/cleanup/run.sh --dry-run` to see JSON findings. This
works with no index present; the phase receipt records what was unavailable.
3. Run `bash ~/workspace/experiments/agent-skills/skills/cleanup/run.sh --plan` to generate a readable cleanup plan.
4. Run `bash ~/workspace/experiments/agent-skills/skills/cleanup/run.sh --script-scanability` to run only the
non-mutating script readability pass.
5. Run `bash ~/workspace/experiments/agent-skills/skills/cleanup/run.sh --public-readiness` to run only the
non-mutating public-readiness/security lane.
6. Run `bash ~/workspace/experiments/agent-skills/skills/cleanup/run.sh --quality-gate` for the selected
non-mutating quality-gate lane.
7. Run `bash ~/workspace/experiments/agent-skills/skills/cleanup/run.sh --memory-index` for Memory
searchability and local offline code-symbol artifacts.
8. For dirty worktrees, run `bash ~/workspace/experiments/agent-skills/skills/cleanup/run.sh --worktree-audit --output artifacts/cleanup/worktree_audit.json`.
9. Use `--registered-worktree-audit` for stray secondary worktrees; review the
audit before rescue/prune.
10. If a clean worktree is needed for commit isolation, record both paths in the
plan: the live repo of record and the temporary commit worktree.
Ver no GitHub