# Contributing

## What's Welcome

- Bug fixes with a clear reproduction case
- New passive capture modules (stick to the module pattern in `modules/passive/`)
- Hardware support for additional SBCs
- Documentation improvements

## What's Not Welcome

- Active modules that target specific commercial services (keep it protocol-level)
- Features that reduce OPSEC (fingerprints, banners, hardcoded strings)
- Breaking changes to the state machine API without a migration path

## Module Pattern

New modules implement the `BaseModule` interface:

```python
class MyModule(BaseModule):
    name = "my_module"
    tier = "passive"          # or "active"
    requires = ["root"]       # capabilities needed

    def start(self): ...
    def stop(self): ...
    def status(self) -> dict: ...
```

Modules must not block the main event loop. Use threads or asyncio internally.

## Testing

```bash
python3 -m pytest tests/
```

Tests that require root or live network access are marked `@pytest.mark.requires_root` and skipped in CI. Write unit tests for logic that doesn't need hardware.

## Submitting Changes

1. Fork the repo
2. Branch from `main`
3. Write a test if the change has logic worth testing
4. Open a PR with a description of what changed and why

No CLA. MIT License applies to all contributions.
