# Review Criteria

Project-specific review guidelines for bpftop. Reviewers (human and automated)
should check these in addition to general code quality.

## Safety

- Every `unsafe` block has a `// SAFETY:` comment that explains the invariant.
- FFI boundaries (libbpf-rs, libbpf-sys) validate pointers and return codes
  before use. No unchecked `ptr::read` on user-influenced data.
- File descriptors from BPF syscalls are wrapped in `OwnedFd` so they cannot
  leak on error paths.
- No `unwrap()` or `expect()` on fallible operations in runtime code paths.
  Use `anyhow` context instead. `Mutex::lock().unwrap()` is acceptable
  (poisoned locks indicate a bug). Tests may use `unwrap()`.

## BPF

- Changes to `src/bpf/pid_iter.bpf.c` must remain verifier-friendly: bounded
  loops, no unbounded memory access, only approved BPF helpers.
- Do not edit `pid_iter.skel.rs` — it is generated by `build.rs`.
- If adding new BPF maps or programs, update the skeleton builder in `build.rs`.

## Performance

- This tool collects stats every second in a hot loop. Avoid allocations in
  the per-tick update path (`app.rs` update logic, `bpf_program.rs` stat
  collection).
- Sorting and filtering happen on every frame. Keep the data set small and
  the comparisons cheap.
- Do not hold locks or block on I/O in the render path.

## TUI (ratatui)

- UI code lives in `src/main.rs` (rendering) and `src/app.rs` (state).
  Render functions take `&mut App` for scroll state and graph bounds, but
  should not perform I/O or modify application-level state beyond what
  the UI needs to display the current frame.
- New widgets or views should follow the existing pattern: state in `App`,
  rendering in a dedicated function called from the main draw closure.
- Test that the UI does not panic on zero-length data (no BPF programs
  loaded, empty filter results).

## Multi-architecture

- CI builds for both `x86_64-unknown-linux-gnu` and
  `aarch64-unknown-linux-gnu`. Do not add platform-specific code without
  gating it behind `#[cfg(target_arch = ...)]`.
- New dependencies must support both targets. Check before adding.
- Build changes must work with `cargo` on both x86_64 and aarch64.

## Dependencies

- Keep the dependency footprint small. This ships as a single static binary.
- New crates need justification — prefer the standard library or existing
  dependencies when possible.
- Flag any new crate that uses `unsafe` or includes a `build.rs` with native
  compilation.
