# 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
| [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.
## 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.
## 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.