# Arc – AGENTS.md Arc is a delta-based version control system written in Rust. See `docs/spec.md` for the full specification. ## Required Context - **Always load the `rust` skill** before writing or modifying any Rust code in this project. - **Always read `docs/spec.md`** before starting any implementation work. It contains the full specification, design rules, command definitions, and phased implementation plan that all changes must conform to. ## Build & Quality Commands All commands **must** be run inside the Nix dev shell. `cargo build` alone is **not** a valid build method. ```bash # Format code nix develop -c cargo fmt # Type/compilation check nix develop -c cargo check # Lint (must produce zero warnings) nix develop -c cargo clippy -- -D warnings # Run all tests nix develop -c cargo test # Full Nix build (the only valid build method) nix build ``` Run in this order: `fmt` → `check` → `clippy` → `test` → `nix build`. ## Project Structure ``` arc/ ├── src/ │ ├── main.rs # Entry point, CLI dispatch │ ├── cli.rs # Clap CLI definitions and alias expansion │ ├── model.rs # Core data model (commits, deltas, metadata) │ ├── repo.rs # Repository operations (init, state) │ ├── store.rs # ZSTD + bincode storage layer │ ├── tracking.rs # Auto-change detection │ ├── diff.rs # Diff computation │ ├── merge.rs # Three-way merge │ ├── refs.rs # Bookmarks and tags │ ├── inspect.rs # log, show, history commands │ ├── modify.rs # revert, reset, graft commands │ ├── stash.rs # Named stash system │ ├── config.rs # YAML config (local + global, rule 21) │ ├── ignore.rs # .ignore / .arcignore support │ ├── signing.rs # Optional SSH key commit signing │ ├── bridge.rs # Git bridge (push/pull/clone/migrate/sync) │ ├── remote.rs # Remote management │ ├── resolve.rs # Commit/ref resolution │ ├── check.rs # Validation utilities │ ├── error.rs # Error types (anyhow for app, thiserror for lib) │ └── ui.rs # Terminal output formatting (colored) ├── tests/ # Integration tests (one file per feature area) ├── docs/ │ └── spec.md # Full specification and implementation plan ├── Cargo.toml ├── flake.nix # Nix flake (nixpkgs-unstable, flake-parts, fenix, crane) └── flake.lock ``` ## Key Design Rules - **Delta-based, not snapshot-based.** Commits store incremental deltas, not full snapshots. - **No staging area.** Changes are automatically tracked; `arc commit` captures the full worktree diff. - **Bookmarks, not branches.** `arc mark` manages bookmarks; they map to git branches when pushed. - **Tags are immutable.** Once created, tags cannot be modified. - **Commits are immutable.** Previous commits cannot be edited or amended. - **Storage format:** ZSTD-compressed bincode for deltas and commit data. - **Config format:** YAML. Local config takes precedence over global (rule 21). - **Ignore files:** `.ignore` or `.arcignore`. - **Default bookmark:** `main`. **Default remote:** `origin`. - **Aliases** defined in config are expanded at CLI level before dispatch. - **Git bridge:** All remote operations (push, pull, clone, migrate, sync) use `git2` for compatibility. - **Commit signing:** Optional, via SSH keys (ed25519). ## Dependencies | Crate | Purpose | |---------------|----------------------------------------------| | `clap` | CLI parsing with derive macros | | `serde` | Serialization/deserialization | | `serde_yaml` | YAML config files | | `bincode` | Binary serialization for delta storage | | `zstd` | ZSTD compression for stored deltas | | `sha2` | SHA-256 commit hashing | | `hex` | Hex encoding for commit IDs | | `git2` | Git bridge (vendored libgit2 + openssl) | | `ssh-key` | SSH key commit signing (ed25519) | | `colored` | Terminal color output | | `tempfile` | Temporary directories in tests (dev-dep) | ## Testing Conventions - All tests live in the `tests/` directory as integration tests (one file per feature area). - Tests must use `tempfile::TempDir` for isolated repositories. - Test both happy paths and error/edge cases. - Use descriptive test function names that explain the behavior under test. - Run tests with: `nix develop -c cargo test` ## Commit Conventions Use conventional commits: - `feat: ` — new features - `fix: ` — bug fixes - `refactor: ` — code changes that are not features or fixes - `docs: ` — documentation changes - `build: ` — build system changes - `test: ` — test additions or changes ## Code Style - Follow standard Rust naming conventions (snake_case functions, PascalCase types). - Use `anyhow` / `thiserror` for error handling; no `.unwrap()` in production code. - Prefer `&str` over `&String`, `&[T]` over `&Vec` in function parameters. - No `#![deny(warnings)]` in crate roots; use clippy flags instead. - Do not add code comments unless the code is genuinely complex.