- Rust stable 1.96+
- Rust nightly (for
rustfmt) cargo-machete(unused dependency detection)cargo-audit,cargo-deny(supply chain safety)cargo-llvm-cov(coverage)cargo-semver-checks(SemVer compliance, optional)cargo-mutants(mutation testing, optional)cargo-hack(feature matrix checks, optional)typos,taplo,shellcheck,actionlint(non-Rust lint, required bymake lint)
All contributors must read and understand conventions.md before contributing. The conventions cover code style, testing requirements, file organization, and security practices. Submissions that do not follow these conventions will be rejected.
make build
make release
make checkmake test
make mutants # mutation testing (cargo-mutants)Security is enforced at every stage of development.
cargo audit and cargo deny check are run as part of
the make audit target. The deny.toml config bans
wildcard version requirements, unknown registries, and
unknown git sources. Multiple versions of the same crate
produce a warning. All crates enforce
#![deny(unsafe_code)] and Clippy runs with
-D warnings (zero tolerance).
Formatting requires nightly (group_imports and
imports_granularity are nightly-only). Both stable and
nightly toolchains must be installed.
make fmt # format all code
make lint # check formatting + clippymake doc # build docs with warnings deniedAll items (public and private) require /// doc
comments. The missing_docs and
missing_docs_in_private_items lints enforce this at
compile time.
Rustdoc warnings are denied globally via
.cargo/config.toml (rustdocflags = ["-D", "warnings"]),
so cargo doc always enforces doc quality even
outside Make.
make coverage # HTML coverage report
make coverage-check # fail if below thresholdRequires cargo-llvm-cov. The gate fails below 90%
line coverage or 80% region coverage. Region coverage
counts each branch of each condition, so untested error
paths fail the gate even when every line executes.
make semver # cargo semver-checksRequires cargo-semver-checks. Run before releases to
catch breaking API changes that were not reflected in
the version bump.
See release.md for versioning, the pre-release checklist, tagging, container publishing, and the release pipeline.
All repositories in the praxis-proxy organization
use a consistent workflow for planning, prioritizing,
and tracking work.
Milestones represent a body of work toward a shared goal (e.g. a release, a feature area, or a hardening pass). Every issue and pull request should belong to a milestone. Milestones provide scope boundaries and help answer "what ships together?"
Priority is a native GitHub issue field (a single-select field on the issue itself, not a label). Every triaged issue should have exactly one priority:
| Priority | Description |
|---|---|
Urgent |
Must be worked on immediately before anything else |
High |
Needs to be worked on immediately, defer to urgent |
Medium |
Resolve after high and urgent |
Low |
Resolve after all other priority levels |
When picking up work, address issues in priority order: urgent first, then high, medium, and low. Urgent and high-priority work is assigned by a maintainer, never self-assigned (see Picking Up Work).
GitHub project boards visualize the state of work across milestones. Use boards to track issues through their lifecycle (backlog, in progress, in review, done). Boards are the primary tool for stand-ups and status checks. An issue that is not on a board has not been triaged.
An issue is triaged once a maintainer has given it a milestone and added it to a project board. Only maintainers triage.
Maintainers, for this purpose, are members of the teams
listed in MAINTAINER_TEAMS in
.github/workflows/issue-triage.yaml: the same teams
that bypass the PR size and description checks.
Adding a milestone or a project board does not, on its own, triage an issue: only a maintainer can, and only by doing both.
Contributors may self-assign an issue only when both of the following hold:
- It is triaged (has a milestone and is on a board).
- Its priority is
MediumorLow.
Urgent and high-priority issues, and any un-triaged issue, must be assigned by a maintainer. If a non-maintainer self-assigns or otherwise moves an un-triaged issue (adds a milestone or a project board), the issue triage workflow resets it: it removes every assignee, its milestone, and every project board, then comments explaining that a maintainer must triage the issue before it can be assigned or prioritized. For an issue that is already triaged, self-assigning urgent or high-priority work is reverted the same way. Ask a maintainer to triage or assign it instead.