Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ go test ./internal/ -run TestGolden -update # regenerate golden files after
| `docs/SPEC.md` | behavior the user approved: commands, flags, JSON, safety levels, ecosystem catalog, config | behavior changes |
| `docs/ARCHITECTURE.md` | module boundaries, cross-module contracts, adding an ecosystem | a boundary or contract changes |
| `plugins/devclean/skills/devclean/SKILL.md` | the Claude Code skill that runs the binary for the user | commands, flags, JSON fields or safety gates change |
| `docs/decisions/` | one costly-to-reverse choice per file: decision, verification, rationale, rejected alternatives | such a choice is made or reversed |
| `docs/decisions/` | one costly-to-reverse choice per file: decision, rationale, rejected alternatives | such a choice is made or reversed |
| `CHANGELOG.md` | release sections written by release-please from PR titles | never by hand (`docs/decisions/release-please.md`) |

- Update docs in the same commit as the code.
Expand Down
9 changes: 0 additions & 9 deletions docs/decisions/clone-aware-size.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@

The per-file block sum is kept as `allocated_size` when larger.

## Verification

```bash
go test ./internal/scanner/ -run 'Clone|Pnpm' -v
go test ./internal/output/ -run SharedBlocks -v
```

Measured 2026-10-02: Chrome copies 11.3 GB → 0.76 GB; a pnpm `node_modules` 448 MB → 3.9 MB; home scan time unchanged (~60 s).

## Rationale

- Sizes that are mostly shared blocks (Chrome copies ~15×) lead users to delete for space that never comes back.
Expand Down
7 changes: 0 additions & 7 deletions docs/decisions/hf-shared-blobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@

Shared blobs are sized and deleted by their `<hash>.refs` manifests with huggingface_hub's rules (`utils/_shared_blobs.py`): a reference counts only while its symlink still points at the blob, and a blob whose manifest is unreadable or whose `<hash>.lock` is held is never deleted.

## Verification

```bash
go test ./internal/scanner/ -run 'TestLLMScanner_HF' -v
go test ./internal/cleaner/ -run 'Release' -v
```

## Rationale

- Model directories hold only symlinks, so without the store GB of weights went unreported and deleting a model freed nothing.
Expand Down
7 changes: 0 additions & 7 deletions docs/decisions/one-filesystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@

Finding, sizing and the pre-delete check walk through `fstree`, which stays on the root's filesystem (like `du -x`). A directory on another device, of unknown device, or unreadable is not entered and is returned as skipped. Path removal (including dry-run) is refused when `fstree` skipped any directory inside the item. To scan a mount, pass it as `--path`.

## Verification

```bash
go test ./internal/fstree/ -run 'OtherFilesystem|WithoutDevice|CheckOneFilesystem' -v
go test ./internal/cleaner/ -run 'TestRefusesUncheckedTree' -v
```

## Rationale

- Mounts under the root are not this machine's reclaimable disk. Example: Xcode CoreDevice's `~/Library/Developer/CoreDevice/DeviceFS`, measured at ~4 s per directory read.
Expand Down
6 changes: 0 additions & 6 deletions docs/decisions/prune-non-project-trees.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ The walk engine skips these trees whole — no artifact matching, no project con

When adding an ecosystem or rule, scan that tool's real SDK/toolchain checkout and verify what gets flagged. A scanner's own false positive is fixed in that scanner's PR.

## Verification

```bash
go test ./internal/scanner/ -run 'TestWalkExcludesInstalledPackageTrees|TestFlutterWalk' -v
```

## Rationale

- Each package in an installed-package tree, including the runtime an app ships inside its bundle, carries its own marker (`package.json`, `setup.py`, `go.mod`). Without pruning it roots a project, and its shipped `dist/`, `__pycache__` or `vendor/` matches as `safe` output — deleting the `dist/` of the npm bundled in a GitHub Actions runner breaks the runner. A project's own `node_modules` matches as an artifact before the name check, so it is still reported.
Expand Down
11 changes: 1 addition & 10 deletions docs/decisions/release-please.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,9 @@ release-please keeps a release PR open on `main`. Merging it bumps the version,

- Version: Conventional Commits, `feat` bumps minor, `fix`/`perf` bump patch; below 1.0 a breaking change bumps minor (`bump-minor-pre-major`).
- Sections: `feat` → Added, `fix` → Fixed, `perf`/`revert` → Changed; other types are hidden.
- The repository squash-merges only, with the PR title as the commit title, so the PR title is what release-please reads.
- Token: the default `GITHUB_TOKEN`. Its tag does not trigger other workflows, so GoReleaser runs as a job of the release-please workflow. CI on the release PR waits for a manual approval because `GITHUB_TOKEN` opened it.

## Verification

```bash
goreleaser check
```

CI runs the same check on every PR. The first release PR shows the generated version and section; its merge run shows the Release with assets.

The repository squash-merges only, with the PR title as the commit title, so the PR title is what release-please reads.

## Rationale

- Releases stalled for five months when version, changelog cut and tag were manual steps; an always-open release PR makes a release one merge.
Expand Down
8 changes: 0 additions & 8 deletions docs/decisions/symlink-no-follow.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@

`fstree` never descends into a symlink and never matches one as an artifact, even when it is named like one (a symlinked `node_modules`, as pnpm and some monorepos produce). Only the scan root is read through, and only for `--path`. Deleting a symlink removes only the link; the cleaner's cross-filesystem trash copy recreates symlinks as links.

## Verification

```bash
go test ./internal/fstree/ -run 'Symlink' -v
go test ./internal/scanner/ -run 'Symlink' -v
go test ./internal/cleaner/ -run 'TestCopyTree_PreservesSymlinkAsLink' -v
```

## Rationale

- A symlink's target is real content that lives on disk elsewhere, so following it would double-count that space and inflate the reported reclaimable total.
Expand Down
Loading