diskr 0.1.60

Lightweight terminal file explorer and disk/storage manager for macOS
# AGENTS.md — diskr agent protocol

Instructions for any coding agent (Claude Code, Junie, Codex, or otherwise)
working in this repository. Follow this file exactly; it is the single source
of truth for the development workflow. Human contributors follow the same
process.

## Project summary

diskr is a macOS-only terminal disk/storage manager written in Rust
(MSRV 1.88, ~6k lines, no async runtime). The TUI is the product; CLI report
modes (`--top`, `--reclaim`, `--save`/`--diff`, `--space`, `--packages`)
mirror its intelligence for scripting. The scanner is syscall-bound
(`getattrlistbulk(2)`); do not assume more threads or bigger buffers improve
scan performance.

## Documentation map

| File | Purpose | You update it when |
| --- | --- | --- |
| [README.md]README.md | User-facing docs, key table, release flow | Keys, CLI flags, or user-visible behavior change |
| [CHANGELOG.md]CHANGELOG.md | What shipped, per version | Every behavior change (under `[Unreleased]`) |
| [docs/ISSUES.md]docs/ISSUES.md | Living issue tracker | Starting, finishing, or discovering work |
| [ROADMAP.md]ROADMAP.md | Product direction, feature-level plans | A feature ships or direction changes |
| [docs/AUDIT.md]docs/AUDIT.md | **Frozen archive** of the 2026-06 audit | Never. Read-only reference for findings #1-#70 |

**Issue numbering:** a reference like "issue #21" or `(#21)` always means an
entry in [docs/ISSUES.md](docs/ISSUES.md) (numbering inherited from the audit
findings in docs/AUDIT.md). This repo does not use GitHub issues. If an ID is
not in ISSUES.md's index, it is an already-resolved finding — check the
Resolved section and the matching finding in docs/AUDIT.md before concluding
it does not exist.

## The workflow (non-negotiable)

1. **Before starting any work**, read `docs/ISSUES.md` and the `[Unreleased]`
   section of `CHANGELOG.md`. Other agent sessions run in parallel and commit
   mid-task: re-read these files (and any source file) immediately before
   editing them, and expect occasional transient breakage from concurrent
   commits — check `git log` before assuming your change caused a failure.
2. **Claim your work — and track untracked work.** If you are working on a
   tracked issue, set its status line to
   `In Progress (YYYY-MM-DD, <session/agent>)` in `docs/ISSUES.md`. If Milo
   asks for a change that is not in the tracker — "make [x] faster", "change
   this UI element from [x] to [y]", a new flag, a behavior tweak — add an
   issue for it first (next free ID, type Perf/UX/Feature/etc., a few lines
   describing the request and intended approach), mark it In Progress, and
   from there treat it exactly like a listed issue: same validation, same
   changelog entry referencing the ID, same move to Resolved, same release.
   The tracker is the complete record of all work, not just audit findings;
   "it wasn't a listed issue" is never a reason to skip the protocol. Never
   reuse or renumber IDs.
3. **No change goes undocumented.** Every commit that changes behavior must
   update `CHANGELOG.md` under `[Unreleased]` in the same commit (Added /
   Changed / Fixed / Removed). Pure refactors, test-only, and doc-only commits
   need no changelog entry.
4. **Found a bug you are not fixing right now?** Add it to `docs/ISSUES.md`
   with the next free ID. Found and fixed one inline? Still add it, marked
   Resolved, so the ID and history exist.
5. **When you finish an issue:** move its entry to the Resolved section of
   `docs/ISSUES.md` with the version (or `Unreleased`), and make sure the
   changelog entry references the issue ID, e.g. `(#52)`.
6. **Keep user docs in sync.** If you add/change a key binding or CLI flag,
   update the README key table and `print_help` in the same commit (issue #40
   exists because this was skipped).
7. **Never edit `docs/AUDIT.md`.** It is a frozen snapshot; several of its
   status checkboxes are known to be wrong. Current truth lives in
   `docs/ISSUES.md` and `CHANGELOG.md`.
8. **Do not revert other sessions' documentation edits.** If `docs/ISSUES.md`
   or `CHANGELOG.md` changed under you, merge your entry in; never overwrite.
9. **Ship completed work.** When Milo asks for an issue fix or a change, the
   task is not done at a local commit: complete the release process below so
   the change is pushed to GitHub (`main`) and published to crates.io. Only
   skip the release if Milo explicitly says not to release, or if the change
   is doc-only / has no behavior effect — those are still pushed to `main`,
   just without a version bump and tag.
10. **Track deferred work at the moment of deferral.** If an issue, finding,
    or plan splits work into phases ("Phase 2", "follow-up", "later"), the
    deferred part gets its own issue in `docs/ISSUES.md` before the delivered
    part is marked complete — a checked box reads as fully resolved and
    buries anything still pending inside it. Likewise, promote requirements
    that exist only in rationale prose ("mark stale, refresh on demand") to
    explicit spec bullets or issues: completion is verified against bullets,
    so prose-only requirements ship by accident or not at all. (Added after
    audit finding 19's Phase 2 went untracked for weeks; see #82-#86.)

## Validation before every commit

```sh
cargo fmt -- --check
cargo check --locked
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --locked
```

Caution: never add tests that touch real user state (Trash, `~/Library`,
Finder automation) — see issue #44. Destructive operations must be behind
injectable runners in tests.

## Attribution policy

Codex, Claude, Claude Code, and other coding agents are tools, not project
contributors. GitHub-visible project history must attribute code, docs,
release notes, tags, and other published artifacts to the human maintainer,
not to an agent.

- Before any commit, tag, push, or release action, verify `git config user.name`
  and `git config user.email` are Milo's human Git identity, and verify no
  `GIT_AUTHOR_*` or `GIT_COMMITTER_*` environment variable names an agent.
- Do not add `Co-authored-by`, `Generated with`, `Signed-off-by`, release-note
  credit, changelog credit, docs credit, or metadata that names Codex, Claude,
  Claude Code, OpenAI, Anthropic, or another agent/vendor as an author,
  co-author, contributor, generator, releaser, or implementer.
- If a local tool tries to add agent attribution automatically, remove that
  attribution before committing. If it cannot be disabled, stop and ask Milo
  before creating commits, tags, or releases.
- Before pushing a release tag, inspect the commits included since the previous
  release tag. If any commit author, committer, trailer, or generated release
  note would make Codex, Claude, or another agent appear as a contributor,
  stop before publishing and ask Milo how to proceed.
- Do not rewrite or edit existing commits, tags, GitHub releases, or published
  crates to remove prior attribution unless Milo explicitly requests that
  history-changing work.

## Release process

Releases go directly on `main` (no feature branch): commit → tag → publish.
This is the default end state of any requested fix or change (workflow
rule 9). Publishing is automated: pushing a `vx.y.z` tag triggers the GitHub
Release workflow, which validates the tag, publishes to crates.io, and
creates the GitHub release. **Never run `cargo publish` manually.**

1. `git pull --rebase` first — parallel sessions release too. Pick the next
   unused patch version (check `Cargo.toml` and `git tag` after pulling).
2. Run the full validation set plus `cargo package --locked`.
3. Move the `[Unreleased]` changelog content into a new
   `## [x.y.z] - YYYY-MM-DD` section (leave `[Unreleased]` present and empty).
4. Bump `version` in `Cargo.toml`, refresh `Cargo.lock`.
5. Commit (imperative mood, short title), push to `main`, then create and
   push the matching tag `vx.y.z`.
6. If the push or tag is rejected because another session released in the
   meantime, rebase, re-bump to the next free version, and retry — never
   force-push or delete tags.
7. Confirm the Release workflow succeeded (`gh run list --workflow Release
   --limit 1` or the Actions tab) before reporting the task complete; if it
   failed, fix and re-release rather than leaving a half-published version.

## Conventions

- Commits: imperative mood, short titles. Reference issue IDs where relevant.
- No emojis in code, docs, or commits.
- Prefer editing existing files over creating new ones; no new doc files
  unless this protocol changes.
- Comments only where the logic is not self-evident; match surrounding style.