# Contributing to Charybdis Contributions are welcome! Whether it's a bug report, feature idea, documentation improvement, or code contribution. ## Getting Started ### Prerequisites - Rust stable (1.79+) - PostgreSQL 14+ - protoc (Protocol Buffers compiler) ### Development Setup ```bash # Clone the repo git clone https://github.com/YOUR-ORG/charybdis.git cd charybdis # Copy config cp config.toml.example config.toml cp .env.example .env # Edit .env with your PostgreSQL credentials # Build cargo build --workspace # Run tests cargo test -p charybdis # Run the server cargo run -p charybdis-server ``` ### Project Structure ``` src/ Core library (catalog, findings, scanners, security) charybdis-server/ Deployable binary (links core + plugins) plugins/ External integrations (DefectDojo, Keycloak, etc.) proto/ Protocol Buffer definitions ``` ## How to Contribute ### Reporting Bugs Open an issue with: - What you expected to happen - What actually happened - Steps to reproduce - Rust version (`rustc --version`) and OS ### Proposing Features Open an issue describing: - The problem you're trying to solve - Your proposed approach - Any alternatives you considered ### Submitting Code 1. Fork the repo and create a branch from `main` 2. Make your changes 3. Ensure `cargo fmt`, `cargo clippy`, and `cargo test` pass 4. Write a clear commit message explaining the *why* 5. Open a PR against `main` ### Adding a Scanner Parser To add support for a new scan format: 1. Create `src/scanners/your_format.rs` 2. Implement the `ScannerParser` trait 3. Register it in `ParserRegistry::with_builtins()` (or via plugin `contributed_parsers()`) 4. Add tests with sample data ```rust pub struct YourFormatParser; impl ScannerParser for YourFormatParser { fn format_id(&self) -> &str { "your-format" } fn description(&self) -> &str { "Description of the format" } fn parse(&self, data: &[u8]) -> Result { // Parse and normalize findings } } ``` ## Code Style - Run `cargo fmt` before committing - Run `cargo clippy` and address warnings - No comments unless the *why* is non-obvious - Prefer exhaustive matches over wildcards for proto enums ## Architecture Decisions - Security features belong in `src/` (core), not in `plugins/` - Plugins are for external integrations (Slack, Jira, DefectDojo sync) - All API is gRPC-first, other interfaces are adapters - Database schema never changes (protobuf handles evolution)