6.9 KiB
Project Standards: Code & Documentation
This document defines the absolute highest standards for the development of the Voice App project. All contributors must adhere to these rules strictly to ensure maximum performance, security, and maintainability.
1. Rust Coding Standards
1.1 Strict Linting & Safety
The project enforces strict, zero-tolerance compiler checks. Every crate must begin with (or include in Cargo.toml as workspace lints):
#![forbid(unsafe_code)]
#![deny(clippy::all, clippy::pedantic)]
#![deny(clippy::unwrap_used, clippy::expect_used)]
- Unsafe Code: Completely banned. If a dependency requires
unsafe, it must be highly audited and isolated. - No Unwraps:
unwrap()andexpect()are forbidden in production code. You must handle theResultorOptiongracefully and bubble it up using the?operator.
1.2 Error Handling
- Libraries (
core_protocol): Must define their own custom error enumerations usingthiserror. Do not panic. - Binaries (
client_node,server_node): Useanyhow::Resultfor application-level error bubbling. All bubbled errors must be logged usingtracing::error!before the process safely terminates or restarts the specific actor.
1.3 Concurrency & The Actor Pattern
- No Shared Mutexes for Data Flow: Passing an
Arc<Mutex<State>>directly between the Tokio network background thread and theeguiUI thread is prohibited, as it causes stuttering. - Enforce the Actor Pattern: Use
tokio::sync::mpsc(UI -> Network) andtokio::sync::watch(Network -> UI) for all cross-thread communication. - Blocking Operations: Database queries (
sqlxis async so it's fine), heavy cryptography (e.g., Argon2 hashing), or file I/O must never run on the main Tokio executor thread. They must be offloaded usingtokio::task::spawn_blocking.
1.4 High-Performance Audio Rules
- Lock-Free Audio Threads: The
cpalaudio input and output callbacks operate in real-time. You are strictly forbidden from placingMutex::lock(), network socket calls, or heap memory allocations (Vec::new(),String::from()) inside the audio callback. - Zero-Copy Routing: The Server's UDP relay must utilize the
bytes::Bytescrate to share network packet payloads via reference counting. It must never clone raw arrays when broadcasting to multiple users in a channel.
2. Documentation Standards
2.1 The "Why", Not the "What"
Code should be readable enough to explain what it is doing. Inline comments must explain why a specific decision was made (e.g., "We pad this buffer to 960 samples because Opus strictly requires a 20ms mathematical frame, otherwise it throws an invalid packet error.").
2.2 Docstrings
Every public struct, enum, fn, and mod must have a standard /// docstring.
Functions returning a Result must include an # Errors section.
/// Encodes raw f32 audio samples into a compressed Opus frame.
///
/// # Arguments
/// * `pcm_data` - A slice of exactly 960 audio samples representing 20ms of audio.
///
/// # Errors
/// Returns `AudioError::InvalidFrameSize` if the length of `pcm_data` is not exactly 960.
pub fn encode_frame(pcm_data: &[f32]) -> Result<Vec<u8>, AudioError> { ... }
2.3 Module Level Documentation
Every lib.rs or mod.rs file must begin with a //! documentation block explaining the architectural purpose of that module. If a developer opens a file, the first paragraph should tell them exactly what the module's responsibility is.
2.4 Architecture Decision Records (ADRs)
If you propose a fundamental change to the architecture (e.g., changing the database from SQLite to PostgreSQL, or swapping Extism for Wasmtime), it must first be documented in a new file under Documentation/ADR/ detailing the Context, Decision, and Consequences.
3. Security Standards
- Zero-Knowledge Logging: Never log passwords, Argon2 hashes, raw JWT tokens, or UDP Session Tokens via the
tracingframework. Use[REDACTED]if you must log an event involving secure data. - Memory Sanitization: Highly sensitive cryptographic material in memory should utilize the
secrecycrate to ensure it is Zeroized (wiped from RAM) the moment it falls out of scope. - Strict API Validation: Never trust the client. The server must validate the lengths, bounds, and permissions of every single TCP event and UDP packet before processing it.
4. Git & Workflow Standards
- Conventional Commits: Commit messages must follow the standard:
feat: added global hotkeys for PTTfix: resolved Opus frame alignment crashrefactor: migrated UDP payload to bytes cratedocs: updated API documentation for Wasm plugin
- CI/CD Constraints: No code is merged into
mainunless it successfully passes:cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --all
5. Testing & Quality Assurance
- Property-Based Testing: Network boundaries (especially the UDP parser) must use property-based testing (e.g., the
proptestcrate) to throw random, garbage bytes at the decoders. A malformed network packet must never cause the server or client to panic. - Mocking Hardware Interfaces: To ensure the CI pipeline can run headless without physical microphones, the audio capture interface (
cpal) must be abstracted. The test suite will feed deterministic "sine wave"f32vectors into the DSP pipeline to mathematically verify encoding/decoding. - Unit Testing Core Logic: All state transitions, RBAC permissions, and packet serializers must have 100% test coverage.
6. Cross-Platform Constraints
- Strict OS Agnosticism: Core business logic must remain OS-agnostic. Any OS-specific system calls (like Windows Registry Hooks or Linux
alsatweaks) must be isolated behind#[cfg(target_os = "...")]compilation flags. - Fallback Mandate: If an OS-specific feature is added (e.g., a Windows global hotkey), a functional equivalent or safe fallback must be provided for Linux and macOS in the exact same Pull Request.
- Pathing: Hardcoding
/or\in strings is forbidden. Developers must strictly usestd::path::PathBuffor all file system interactions to ensure Windows/POSIX compatibility.
7. Dependency Management & Telemetry
- Dependency Minimalism: Before adding a new crate to
Cargo.toml, evaluate if the feature can be implemented natively in under 100 lines of Rust. Heavy, sprawling dependencies will be rejected. - Security Auditing:
cargo auditmust be integrated into the CI pipeline to automatically fail builds if a known CVE is discovered in the dependency tree. - Server Telemetry: Beyond text logs, the server must expose a
/metricsPrometheus endpoint to track high-level health metrics: concurrent active users, UDP packet drop rate, Jitter buffer latency spikes, and CPU/Memory usage.