| name | repo-hygiene |
| description | Keep code in git, not in the synced document folder. Sweep a folder for git repos + worktrees, verify branches are on a remote, prune pushed worktrees, and flag code/deps/secrets that leaked into a cloud-sync document library. Powered by the `hygiene` binary. Triggers on "repo hygiene", "clean up worktrees", "is everything pushed", "code leaked into Dropbox/Drive", "prune worktrees", "add the harness to this project". |
| allowed-tools | ["Bash","Read","Write","Edit"] |
repo-hygiene
A Claude Code skill that enforces one boundary: code lives in git
(GitHub/Bitbucket) + ~/code, never in a cloud-sync document folder (Dropbox,
Google Drive, iCloud, OneDrive). It is a thin front-end over the hygiene
binary in this repository.
Why this exists (the lesson)
A ~130k-file document library choked a cloud-sync client. Root cause:
application code, .git, node_modules/.venv, and dozens of git worktrees
had leaked into the document folder. A dependency directory in a cloud-sync
folder is the single most documented cause of the "never finishes syncing"
symptom. After moving all code out, the folder dropped to ~17k real documents.
This skill and the hygiene tool exist so that never recurs.
First: install the binary
The skill calls hygiene. If it is not on PATH:
cd <path to this repo> && make install
Run a read-only sweep
Everything below is READ-ONLY - nothing is moved or deleted:
hygiene scan --json <folder>
hygiene worktree-gc <folder>
hygiene doctor
Flag order matters: put flags BEFORE the folder (scan --json <folder>, not
scan <folder> --json) - the Go flag parser stops at the first non-flag argument.
Read the JSON and summarize for the user: counts of leaked repos / dependency
dirs / secrets, which worktrees are prunable vs blocked, and any secret paths to
move out. THEN propose the next action - never mutate without the user's OK.
The verbs (all --dry-run by default; deletion is always separate and gated)
| Task | Command |
|---|
| Report leaks in a folder | hygiene scan --json <folder> |
| List credential-shaped files | hygiene secret-scan --json <folder> |
| Plan moving a repo out of a sync folder | hygiene eject <repo> |
| Execute the move (preserve → reconstruct → quarantine) | hygiene eject <repo> --force |
| Delete a quarantined source after its retention window | hygiene finalize <folder> |
| Prune pushed worktrees (archives untracked/ignored first) | hygiene worktree-gc <repo> / --force |
| Health check | hygiene doctor (add --deep to scan roots) |
| Install the always-on guards | hygiene install-hooks --apply |
Hard rules (enforced by the binary, restated here)
- Nothing is deleted until it provably exists in 2+ places AND a retention
window has passed.
eject only quarantines (renames) the source; finalize
is the only deleter, and it re-verifies the installed clone (HEAD + fsck), the
preservation bundle, and the local-only snapshot before removing anything.
- Never push work-in-progress to someone else's remote.
eject pushes only
to a remote whose fetch and every push URL classify as your own; otherwise it
preserves via a local git bundle.
worktree-gc --force archives untracked, ignored, AND modified files to a
local non-sync tar BEFORE removing a worktree, never touches the main worktree,
and never prunes a worktree whose branch is not on a remote.
- Credentials never belong in a synced folder -
scan/secret-scan flag
them; move them to a local-only path.
Stamp the discipline into a project
For a shared/collaborative project, stamp the boundary into the project's
CLAUDE.md so any Claude agent working there inherits it, and write a human
START-HERE file:
bash <path to this repo>/skill/apply.sh --dir "<project folder>" --project "Name"
It manages a single block between <!-- BEGIN/END repo-hygiene --> sentinels
(idempotent, replaced in place, existing content preserved) from
harness-block.md, and writes START-HERE.md from the template. Review both
before sharing.
Companion guard
hygiene install-hooks --apply installs the git pre-commit + pre-push hooks
(block staging/pushing dependency dirs or secrets; warn on sync-root), a daily
launchd scan (macOS), and a Claude Code session-start warning. The hooks fail
open - if the binary is absent they never wedge a git operation. This
changes global git behavior - only run --apply with the user's explicit OK.