rsecure 0.5.0

A simple file encryption and decryption tool using AES-GCM.
# AGENTS.md

Context for any AI coding agent working in this repo (Claude Code, OpenCode, Cursor,
Codex, Aider, Zed, …). Keep this file short and authoritative — anything that grows
beyond a quick reference belongs in a dedicated doc and should be linked from here.

## Project

`rsecure` is a small Rust CLI for file encryption using AES-256-GCM via the
[`aes-gcm`](https://crates.io/crates/aes-gcm) crate. It encrypts and decrypts files
or directories in 128 KiB chunks using STREAM (`EncryptorBE32`), parallelized with
`rayon` and shown via `indicatif` progress bars. CLI parsing is `clap` derive.

Source layout:

- `src/main.rs` — entry point, forbids `unsafe` crate-wide.
- `src/cli/``clap` argument definitions.
- `src/commands/` — one module per subcommand (`create_key`, `encrypt_file`, `decrypt_file`).
- `src/file_ops.rs`, `src/utils.rs` — shared helpers.
- `tests/cli.rs` — integration tests via `assert_cmd` + `predicates`.

## Setup & common commands

Rust toolchain is pinned via `rust-toolchain.toml` (currently 1.94.0). Use the
`Makefile` targets when possible — they match what CI runs.

```bash
make test         # cargo nextest run
make lint         # cargo clippy -- -D warnings
make fmt          # cargo fmt --all
make ci           # fmt + lint + test (run before pushing)
make build        # debug build
make release      # release build
```

Run a single test: `cargo nextest run -E 'test(/<name>/)'`.

## Conventions

- **Commits**: Conventional Commits, enforced by [cocogitto]https://docs.cocogitto.io/.
  Use `cog commit <type> "<msg>" [scope]` rather than `git commit -m`. Common types:
  `feat`, `fix`, `chore`, `docs`, `refactor`, `perf`, `test`, `build`, `ci`.
- **No `unsafe`** in `rsecure` itself — `src/main.rs` declares `#![forbid(unsafe_code)]`.
  Dependencies may use unsafe; that is acceptable.
- **Auto-push**: a `post-commit` git hook pushes every commit to `origin/main`. Do not
  `git commit` work-in-progress to `main` — branch first.
- **Pre-commit hook** (`pre-commit.sh`) runs `pre-commit run -a`, `cargo nextest run`,
  `cargo fmt`, and `cargo check`. If a hook fails, fix the underlying issue and create
  a NEW commit — do not bypass with `--no-verify`.

## Releases

A new version is cut with the [release skill](.claude/skills/release/SKILL.md) — invoke
it via "release" / "bump version" in Claude Code, or follow the steps manually. In short:

```bash
cog bump --version X.Y.Z
```

`cog.toml`'s `pre_bump_hooks` update `Cargo.toml` (via `cargo set-version`), refresh
`Cargo.lock`, regenerate `CHANGELOG.md`, and create a tagged bump commit. The
`post_bump_hook` pushes the tag. The `Cargo.toml` version and the latest git tag
MUST stay in sync — verify before and after.

Required local tools: `cog` (cocogitto 7+) and `cargo-set-version` (from `cargo-edit`).

## CI

`.github/workflows/ci-cd.yml` runs on PRs, pushes to `main`/`dependabot/*`, and tag
pushes. Jobs: `security` (cargo-audit + cargo-deny), `linting` (fmt + check), `test`
(`cargo test`), `build` (cross-platform matrix), `goreleaser` and `publish-crate` on
tag. The `security` job also runs weekly on a cron to surface new advisories.

`cargo-deny` policy lives in `deny.toml` — keep advisories at `version = 2` and only
permissive licenses allowed.

## Security

This is a cryptographic tool. Read `SECURITY.md` before changing any code in
`src/commands/encrypt_file.rs`, `src/commands/decrypt_file.rs`, `src/commands/create_key.rs`,
or `src/file_ops.rs`. The threat model and what `rsecure` does and does not guarantee
are documented there. Vulnerability reports go through GitHub Security Advisories —
never open a public issue for a security bug.

## Things to avoid

- Do not introduce `unsafe` (`#![forbid(unsafe_code)]` will fail the build).
- Do not skip pre-commit hooks (`--no-verify`).
- Do not bump the version manually in `Cargo.toml` — use `cog bump`.
- Do not edit `CHANGELOG.md` by hand — it is regenerated by `cog changelog`.
- Do not commit credentials, key files, or `.enc` artifacts; the `.gitignore` covers
  the obvious cases but be aware when adding test fixtures.