- Read ARCHITECTURE.md (or the current design in draft.md) for the high-level architecture.
- Read DEVELOPER_GUIDE.md for a walk-through of the codebase and common workflows.
- Read docs/adr/ for the rationale behind key design decisions.
- Chat with the team in the WeChat group (QR in wechat-group-keeper.png).
We follow the standard development workflow:
- Branch from
dev:git checkout -b yourname/feature-name - Commit in small, logical chunks using Conventional Commits:
feat:,fix:,refactor:,docs:,test:,chore: - Push your branch and open a PR against
dev. - Review — at least one team member must approve before merge.
- Merge — squash-and-merge into
dev.
# 1. Install Rust toolchain + all required tools
cargo xtask setup-dev
# 2. Build the project (no eBPF for a quick check)
cargo xtask check
# 3. Run tests
cargo xtask test
# 4. Open in your IDE — recommended: VS Code with rust-analyzer
code .| Gate | Command | What it checks |
|---|---|---|
| Format | cargo xtask fmt --check |
rustfmt |
| Lint | cargo xtask clippy |
clippy with -D warnings |
| Test | cargo xtask test |
nextest (falls back to cargo test) |
| Audit | cargo xtask audit |
cargo-deny advisories + cargo-audit |
| Bench | CI bench-cmp job |
critcmp pr main → fail if >5% slower |
| Typo | cargo xtask typos |
spell-check comments and docs |
- Check the todo.md task board for planned work.
- Issues tagged
good first issueare suitable for new contributors. - If you're unsure, ask in the WeChat group or open a discussion.
This project follows the Firecracker standard for unsafe code:
#![deny(unsafe_code)]is the default for every crate.- Modules that genuinely need
unsafemust have#![allow(unsafe_code)]at the module level. - Every
unsafeblock must be preceded by a// SAFETY:comment explaining:- The invariant that makes the block sound.
- Why the invariant holds at this call site.
- Each module with unsafe code must have an entry in the crate's
SAFETY.md. - New unsafe code must pass MIRI:
cargo xtask miri.
- Library crates (core, kernel, runtime): use
thiserrorfor structured errors. NoStringin error types — useBox<dyn Error + Send + Sync>for catch-all variants. - Application code (main bin): use
anyhow::Resultfor fallible functions,anyhow::Contextfor adding context.
- Every new Component must have real, noop, and mock implementations — unit-test the real impl with mocked dependencies.
- Protocol parsers that accept external input must have a
cargo fuzztarget. - Hot-path code (
World::get, pipeline channel ops) must have a criterion benchmark and a MIRI run.
crates/
zerotrace-core/ ← Signal types, Error (zero dependencies)
zerotrace-kernel/ ← World, SystemParam, Lifecycle, ConfigBus, Bundle
zerotrace-runtime/ ← PipelineExecutor, BundleLoader
zerotrace-config/ ← YAML parsing, schema, hot-reload
zerotrace-forwarder/ ← HTTP forwarder to server
zerotrace-platform/ ← IMDS, K8s, libvirt metadata
zerotrace-debug/ ← Debug socket, ctl protocol
zerotrace-plugin-abi/ ← Stable C ABI for .so plugins
src/
collectors/ ← All Source implementations
processors/ ← All Processor implementations
reporters/ ← All Reporter implementations
bundles/ ← Bundle registrations
extensions/ ← Extension examples
Dependency direction is strictly one-way: core → kernel → runtime/config → main bin.