CONTRIBUTING.md
Rama main · réplica de lectura del repositorio original.
# Contributing to Hollow
Thanks for wanting to help. Hollow is meant to give people private, distributed communication they can trust and check for themselves.
## Before you start
- **Open an issue first.** If you want to add a feature or make a bigger change, open an issue to talk it through before you write code, so you don't spend time on something that doesn't fit where the project is going.
- **Bug fixes and small improvements** can go straight to a pull request.
- **Read the [Whitepaper](WHITEPAPER.md)** if you're touching cryptography, networking, or sync logic. It explains the protocol design and why it is the way it is.
## Setting up the project
[BUILDING.md](BUILDING.md) covers what each platform needs (Windows, macOS, Linux, Android and iOS) and how to build it.
### Running Rust tests
```bash
cd rust/hollow_core
cargo test --lib
cargo clippy
```
On Windows the test binary loads OpenSSL's DLLs at startup, so put `C:\Program Files\OpenSSL-Win64\bin` on `PATH` first, or it exits with `STATUS_DLL_NOT_FOUND`.
### Regenerating FFI bindings
After any changes to files in `rust/hollow_core/src/api/`, regenerate bindings from the **project root** (not from inside `rust/hollow_core/`):
```bash
flutter_rust_bridge_codegen generate --rust-input "crate::api" --rust-root "rust/hollow_core" --dart-output "lib/src/rust"
```
## Project structure
| Directory | Language | What it does |
|-----------|----------|--------------|
| `lib/` | Dart | Flutter UI, state management (Riverpod), app logic |
| `rust/hollow_core/` | Rust | Networking, cryptography, CRDTs, storage engine |
| `relay-uws/` | C++ | Production relay server (uWebSockets, MIT licensed) |
Rust handles everything security-critical. Dart handles the user interface. They communicate through FFI bindings generated by `flutter_rust_bridge`.
## Writing code
### Rust
- Follow `cargo clippy` recommendations.
- Add `#[serde(default)]` to any new field on a persisted struct (e.g., `ServerState`). Without it, old data missing the new field silently fails to deserialize.
- New `MessageEnvelope` variants go in the appropriate `handle_envelope_*()` handler module, not in `swarm.rs` directly.
- Unit tests go in `#[cfg(test)]` modules within the same file (standard Rust convention).
### Dart/Flutter
- Follow `flutter_lints` / `analysis_options.yaml`.
- Use `ConsumerWidget` or `ConsumerStatefulWidget` to access Riverpod state. Never pass `WidgetRef` as a constructor parameter.
- Use the Hollow design system components (`HollowButton`, `HollowTextField`, `HollowDialog`, etc.) instead of raw Material widgets.
- Use `AnimatedOpacity` for opacity animations, never the `Opacity` widget.
- Text people see in the app uses sentence case for settings labels and never contains an em dash. The full design rules are in [HOLLOW_DESIGN_LANGUAGE.md](reports/reference/HOLLOW_DESIGN_LANGUAGE.md).
### General
- Don't add comments explaining what code does. Only comment when the *why* is non-obvious.
- Don't introduce abstractions beyond what the task requires.
- Never commit secrets, keys, or credentials.
## Submitting a pull request
1. Fork the repository and create a branch from `main`.
2. Make your changes. Keep the diff focused, one concern per PR.
3. Run `cargo test --lib` and `cargo clippy` for Rust changes.
4. Run `flutter analyze` for Dart changes.
5. Write a clear PR description: what changed, why, and how you tested it.
6. Submit the pull request against `main`.
## Reporting security vulnerabilities
If you find a security issue, **do not open a public issue**. See [SECURITY.md](SECURITY.md) for how to report vulnerabilities privately.
## License
By contributing, you agree that your contributions will be licensed under the [AGPL-3.0 License](LICENSE) (client and core) or [MIT License](relay-uws/LICENSE) (relay), matching the component you're contributing to.