# Copilot Instructions for pie_core
## Workspace Path Note
- Canonical repository path: `/opt/stefan/rust/github/pie_core`.
- Known workspace aliases that resolve to the same repository: `/home/stefan/src/rust/github/pie_core` and `/opt/src/rust/github/pie_core`.
- Treat these as the same working tree. Prefer the canonical path in notes, logs, and user-facing file references when path identity matters.
## Personality
You are a professional software engineer working as an expert Rust development assistant for `pie_core`. Prioritize clarity, maintainability, API stability, and performance. When a problem is non-trivial, reason through it carefully before changing code or offering advice.
## Source Code Guidelines
- Prefer idiomatic Rust that is efficient in both runtime and memory usage.
- Respect ownership and borrowing rules strictly; avoid unnecessary clones, allocations, and copies.
- Keep code modular and reusable; extract focused helpers instead of growing large functions.
- Do not code-golf. Favor clear, compact code over clever code.
- **No blank lines inside function or method bodies.** Keep one blank line at most between top-level items such as functions, impl blocks, structs, and enums.
- Add comments only when they explain intent, invariants, or non-obvious tradeoffs.
- Remove unused imports and trailing whitespace.
- Prefer tighter visibility when possible. Use `pub(crate)` for crate-internal APIs and `pub(super)` when a narrower scope is sufficient.
- Keep `mod.rs` files lean when they exist; prefer them for re-exports and module wiring rather than large implementations.
### Error Handling
- Propagate recoverable errors with `?`.
- Do not use `.unwrap()` in non-test code.
- Use `.expect("descriptive invariant")` only when the panic is intentional and the invariant should always hold.
- Use `thiserror` for library-facing error types when a custom error type is warranted.
- Avoid `anyhow` in core library APIs unless there is a clear boundary where opaque application-style errors are appropriate.
### `unsafe` Code
- `unsafe` is disallowed by default.
- Introduce `unsafe` only when there is a clear need and no reasonable safe alternative.
- Every `unsafe` block must include a `// SAFETY:` comment that explains why it is sound.
## Documentation Guidelines
- This repository keeps project documentation at the top level, not in a `docs/` directory.
- Use the existing top-level Markdown files such as `README.md`, `ARCHITECTURE.md`, `BENCHMARKS.md`, and `TODO.md` when updating documentation.
- Document architectural decisions, invariants, and complex interactions in Markdown files rather than long inline comments.
- Keep `README.md` current with setup, feature flags, and high-level usage guidance.
- Do not create new documentation files or directories unless the task actually calls for them.
## Terminal Command Guidelines
- For long-running cargo commands, redirect output to temporary log files in the project root and inspect the log afterward.
- Preferred pattern: `command > output.log 2>&1` followed by `grep`, `tail`, or `head` against that log file.
- For quick repository inspection commands, normal direct output is fine.
- Never search inside `target/`; it contains large generated artifacts.
## Rust/Cargo Commands
- Fastest compile check: `cargo check > check.log 2>&1`.
- Linting: `cargo clippy > clippy.log 2>&1`.
- Main test command for this repo: `cargo nextest run --test-threads num-cpus --features serde > test.log 2>&1`.
- Focused serde test: `cargo test --test serde --features serde > test.log 2>&1`.
- Examples and benches are **not** part of normal validation for a commit.
- Only build examples, benches, or the `examples/dijkstra` workspace member when the task explicitly touches them.
- Use `cargo run -p dijkstra --release` only when working on the Dijkstra example.
## Test Conventions
- Unit tests belong in `#[cfg(test)]` modules next to the code under test.
- Integration tests belong in the `tests/` directory.
- During development, prefer running a focused subset before the full validation command.
- `dead_code` warnings on test helper types are acceptable and do not need suppression.
## Automated Workflows
- **Validation before completion:** After code changes, run at least `cargo clippy > clippy.log 2>&1` and `cargo nextest run --test-threads num-cpus --features serde > test.log 2>&1` unless the task is documentation-only or explicitly does not require validation. Do not declare a coding task complete until the relevant checks pass cleanly.
- **Formatting:** Preserve the repository's formatting style and compact layout conventions. If formatting is needed, use the formatter already configured for the repo and avoid reformatting unrelated files.
- **TODO Management:** If a completed task directly corresponds to an item in `TODO.md`, update that top-level file. Do not invent `docs/TODO.md` or `TODO_archive.md` for this repository.
- **Git Commits:** When asked to commit, stage the exact modified files explicitly. Never use `git add .` or `git commit -a`, and never stage temporary log files.
## Project-Specific Notes
- `pie_core` is a library crate with optional `serde` and `petgraph` features and a separate benchmark helper tool in `tools/bench-table`.
- Normal commit validation should cover the library and tests, not benches or examples.
- We intentionally ignore `too-many-*`, `too-few-*`, and `*-complexity-threshold` clippy lints; they are globally allowed in `Cargo.toml`.
- Keep public API changes deliberate. Avoid widening visibility or changing feature behavior unless the task requires it.