Contributing to PhoinixDR
Thank you for helping build an open, evidence-driven recovery platform.
Ground rules
- Source media is read-only. Do not add any API that can write to a
BlockReadersource. Partition-table repair, if it ever exists, lives in a separately privileged component. - Typed errors in libraries. Library crates use
thiserror;anyhowis allowed only at application boundaries (apps/). - No panics on media-controlled values. Do not use
unwrap,expect,unreachable!or direct slice indexing on values read from disk. Use the bounds-checked readers inphoinix_core::bytesand checked arithmetic inphoinix_core::arith. Test code may opt out with#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::indexing_slicing, clippy::cast_possible_truncation)]. - No
unsafeoutside platform crates. If unsafe is unavoidable, document why, the assumptions, ownership, bounds and lifetimes next to the block. - Filesystem knowledge stays in filesystem crates. Generic crates must not learn NTFS/FAT/EXT specifics.
- Recovery likelihood and assessment confidence are different numbers. Never conflate them.
- Conservative dependencies. Prefer the standard library. New dependencies need a short justification in the pull request.
Before you push
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace
For changes under apps/desktop (its own Cargo workspace plus npm):
cd apps/desktop && npm ci && npm run typecheck && npm test && npm run build
cd src-tauri && cargo fmt --all -- --check && cargo clippy --all-targets -- -D warnings
CI runs the same commands on Linux and Windows.
Architectural decisions
Significant decisions are recorded in docs/decisions/ as ADRs. If you want to
reopen one, open an issue that references the ADR number and explains what has
changed since it was written.
Test fixtures
Disk-image fixtures live compressed under tests/fixtures/ together with a
manifest.json containing ground truth (file names, sizes, SHA-256 digests,
fragmentation and deletion state). Fixtures are produced by the scripts in
tests/generated/; never edit a fixture by hand — change the generator and
regenerate.
Commit style
Use clear, imperative commit subjects prefixed with the affected area when it
helps, e.g. ntfs: reject runlists with zero-length runs.