|
1 | 1 | --- |
2 | | -title: Contributing |
| 2 | +title: Contribution Guidlines |
3 | 3 | --- |
4 | 4 |
|
5 | | -## Guidelines |
| 5 | +## General Principles |
| 6 | +Before contributing, please understand the project's goals and community standards. Legato aims to help **humans** make art and run it on their own hardware. |
6 | 7 |
|
7 | | -**Before working on any new functionality, please open an issue beforehand.** |
| 8 | +### AI Policy |
| 9 | +AI tools may be used for auxiliary tasks (e.g., generating test harnesses, proofreading, refactoring). However: |
| 10 | +* **Low-effort AI:** Pull requests that show clear signs of low-effort AI generation will not be accepted. |
| 11 | +* **Human-Centric Art:** The project **will not** incorporate or promote visuals, art, music, or other creative works that were not made by **humans** on official channels. |
8 | 12 |
|
9 | | -Due to the plugin-oriented nature of Legato, it is unlikely that nodes will be added for every possible use case. However, if something is sufficiently general (e.g., pitch shifting, polyphase resampling), it may be considered. |
| 13 | +### Community & Licensing |
| 14 | +* **Code of Conduct:** We strive for a diverse, respectful community. Please see the *[Berlin Code of Conduct](https://berlincodeofconduct.org/en)* for general guidelines. |
| 15 | +* **Licensing:** Any contributions will fall under the license and additional permissions distributed with the repository. |
| 16 | +* **Logo Usage:** The Legato logo may only be used in non-monetized contexts (e.g., Matrix or Discord). Commercial packages or educational materials not adhering to AGPLv3 or fair use are not permitted. |
10 | 17 |
|
11 | | -Any contributions will fall under the license and additional permissions distributed with the repository. |
| 18 | +## Getting Started |
| 19 | +**Before working on any new functionality, please open an issue.** Due to the plugin-oriented nature of Legato, it is unlikely that nodes will be added for every possible use case. However, if something is sufficiently general (e.g., pitch shifting, polyphase resampling), it will be considered. |
12 | 20 |
|
13 | | -Lastly, I am to have a diverse, respectful community of people that just want to make cool things, and run it on their hardware. |
| 21 | +### Development Setup |
| 22 | +Developers are strongly encouraged to use **Nix** to manage dependencies. This ensures benchmarks, configurations, and tests are reproducible. |
| 23 | +* **Standard Setup:** Clone the repository and use the provided Nix development shell (optionally via direnv). |
| 24 | +* **Non-Nix Setup:** If you choose not to use Nix, you will need a **Rust nightly** toolchain. Note that contributions are still expected to build and run in the Nix environment. |
14 | 25 |
|
15 | | -Please see the [Berlin Code of Conduct](https://berlincodeofconduct.org/en) for general guidelines of what is and is not acceptable. |
| 26 | +## Technical Standards |
| 27 | +Legato maintains strict requirements to ensure stability and real-time audio performance. |
16 | 28 |
|
17 | | -## Development Setup |
| 29 | +### Code Style & Safety |
| 30 | +* **Modeling:** Prefer modeling state and events with `enums` or `bitflags`. |
| 31 | +* **Safety:** `unsafe` code with measurable performance gains is acceptable, provided safety is preferred elsewhere and Undefined Behavior (UB) is checked with **Miri**. |
| 32 | +* **Testing:** Non-trivial code should include at least a few relevant test cases and benchmarks using **Criterion** (with black-boxed inputs/outputs). |
18 | 33 |
|
19 | | -Developers are strongly encouraged to use Nix to manage dependencies. |
| 34 | +### Real-Time & Concurrency |
| 35 | +Code that runs on the audio thread **must be wait/lock-free**. |
| 36 | +* **Prohibited:** Avoid mutexes, condition variables, syscalls, heap allocations, or any blocking synchronization primitives in the audio thread. |
| 37 | +* **Synchronization:** If using channels, queues, or ring buffers, they must be lock-free and non-blocking. Do not assume a standard channel is real-time safe without verification. |
20 | 38 |
|
21 | | -This makes benchmarks, development configurations, and tests reproducible. |
| 39 | +### Performance Optimization |
| 40 | +When optimizing DSP code, follow these steps in order: |
| 41 | +1. **Data Structures:** Use flat buffers or cache-optimized structures. |
| 42 | +2. **Vectorization:** Use chunks_exact where possible for auto-vectorization. Consider polynomial approximations for operations that cannot be efficiently vectorized, or if the cost is too high. |
| 43 | +3. **Branching:** Prefer branching at function entry rather than in hot DSP paths; use branchless solutions where appropriate. |
| 44 | +4. **Memory:** Avoid heap allocations in hot paths; use arenas or preallocation if required. |
| 45 | +5. **SIMD:** Once logic is optimized, consider std::simd(nightly) if it yields measurable gains. |
22 | 46 |
|
23 | | -For now, this is as simple as cloning the repository and using the provided Nix development shell, optionally via `direnv`. While Nix is not required, contributions are expected to build and run in the Nix environment. |
24 | 47 |
|
25 | | -If you do not wish to use Nix (fair enough), you will need a Rust nightly toolchain. |
| 48 | +## Pull Requests and Review |
| 49 | +All pull requests must adhere to the following checklist: |
26 | 50 |
|
27 | | -## Code Style Guide |
| 51 | +* **Issue Reference:** Every PR must reference an existing issue, and the scope must match that issue. |
| 52 | +* **Validation:** All CI checks must pass. Non-trivial changes must include tests. |
| 53 | +* **Benchmarks:** Performance-relevant changes must include benchmarks or detailed justification. |
| 54 | +* **Documentation:** PRs should include a clear description of design decisions and trade-offs. |
28 | 55 |
|
29 | | -* Prefer modeling state and events with enums or bitflags |
30 | | -* Avoid locking primitives in real-time code |
31 | | -* Avoid syscalls or heap allocations in the audio thread |
32 | | -* Non-trivial nodes should include benchmarks using Criterion, with black-boxed inputs and outputs |
33 | | -* unsafe with measurable performance gains is acceptable, but safety should be preferred under most circumstances, provided UB is checked with Miri. |
34 | | -* Non-trivial code should include at least a few relevant test cases |
35 | | - |
36 | | -### Concurrency and Lock-Free Expectations |
37 | | - |
38 | | -Code that runs on the audio thread must be lock-free. |
39 | | - |
40 | | -Avoid mutexes, condition variables, and blocking synchronization primitives. |
41 | | - |
42 | | -If using channels, queues, or ring buffers, they must be lock-free and non-blocking under all expected conditions. Do not assume that a “channel” is suitable for real-time use without verifying its implementation. |
43 | | - |
44 | | -## General Performance Guidelines |
45 | | - |
46 | | -When optimizing DSP code, generally follow these steps: |
47 | | - |
48 | | -* Use flat buffers or cache-optimized data structures |
49 | | -* Consider structuring algorithms to use `chunks_exact` where possible for auto-vectorization, if gains are observed when benchmarking |
50 | | -* Prefer branching at function entry rather than in hot DSP paths. |
51 | | -* Use branchless solutions where appropriate |
52 | | -* Use polynomial approximations for operations that cannot be efficiently vectorized |
53 | | -* Avoid heap allocations and system calls in hot paths; if allocation is required, use arenas or preallocation |
54 | | -* Avoid mutexes or blocking primitives in audio-thread code |
55 | | -* Once these steps are complete, consider `std::simd` (nightly) for further optimization, but make this yields measurable performance gains |
56 | | - |
57 | | -## Pull Requests and Review Process |
58 | | - |
59 | | -All pull requests must adhere to the following: |
60 | | - |
61 | | -* Every PR must reference an existing issue |
62 | | -* The scope of the PR should match the associated issue |
63 | | -* All CI checks must pass |
64 | | -* Performance-relevant changes must include benchmarks or justification |
65 | | -* Non-trivial changes must include appropriate tests |
66 | | -* PRs should include a clear description of design decisions and trade-offs |
67 | | - |
68 | | -PRs that do not meet these requirements may be closed without review. |
69 | | - |
70 | | -## Logo Usage |
71 | | - |
72 | | -The Legato logo may only be used in non-monetized contexts. |
73 | | - |
74 | | -Community spaces such as Matrix or Discord are acceptable. |
75 | | - |
76 | | -Commercial packages of nodes or other educational material that do not adhere to AGPLv3 or are not fair use are not permitted. |
77 | | - |
78 | | -## AI Policy |
79 | | - |
80 | | -AI tools may be used for auxiliary tasks such as generating test harnesses, proofreading documentation, refactoring traits, or general review. |
81 | | - |
82 | | -However, pull requests that show clear signs of low-effort AI generation will not be accepted. |
83 | | - |
84 | | -Legato aims to help HUMANS make art. The project WILL NOT incorporate or promote visuals, art, music, or other creative works that were not made by HUMANS on official channels. |
| 56 | +*Note: PRs that do not meet these requirements may be closed without review.* |
0 commit comments