# Contributing to ContextGuard

Thank you for your interest in contributing to ContextGuard. Whether you are filing a bug report, suggesting a feature, improving documentation, or writing code, your help is appreciated. This guide walks through the process so you can get started quickly.

---

## Table of Contents

- [Ways to Contribute](#ways-to-contribute)
- [Development Setup](#development-setup)
- [Code Standards](#code-standards)
- [Pull Request Process](#pull-request-process)
- [Adding Detection Patterns](#adding-detection-patterns)
- [Testing Guidelines](#testing-guidelines)
- [Documentation](#documentation)
- [Release Process](#release-process-maintainers)

## Ways to Contribute

- **Bug Reports** - Open a GitHub issue with clear reproduction steps, expected behavior, and actual behavior.
- **Feature Requests** - Describe your idea, the problem it solves, and a rough outline of how it might work.
- **Code** - Fork the repository, create a branch, and submit a pull request.
- **Documentation** - Fix typos, clarify explanations, or add examples.
- **Security Issues** - If you discover a vulnerability, do not open a public issue. Follow the process in [SECURITY.md](SECURITY.md).

## Development Setup

Clone the repository and install the package in editable mode with development and optional dependencies:

```bash
git clone https://github.com/contextguard/contextguard.git
cd contextguard
pip install -e ".[dev,all]"
```

Verify everything is working by running the test suite and linter:

```bash
pytest tests/ -v
ruff check contextguard/
```

## Code Standards

All contributions should follow these conventions:

| Area | Standard |
|------|----------|
| Python version | 3.9 and above |
| Type hints | Required for all public APIs |
| Docstrings | Google style, required for classes and public methods |
| Test coverage | New features must include tests (minimum 80% coverage) |
| Line length | 100 characters maximum |
| Linter | `ruff check contextguard/` must pass cleanly |

## Pull Request Process

1. Create a feature or fix branch from `main`:
   ```bash
   git checkout -b feature/your-feature-name
   ```

2. Make your changes and write tests for any new behavior.

3. Run the test suite and linter before committing:
   ```bash
   pytest tests/ -v
   ruff check contextguard/
   ```

4. Write a clear commit message that describes what was changed and why:
   ```bash
   git commit -m "Add detection pattern for Slack webhook URLs"
   ```

5. Push your branch and open a pull request against `main`. In the PR description, include:
   - A summary of the changes
   - The motivation or issue being addressed
   - Relevant test results

## Adding Detection Patterns

### Adding a secret pattern

Open `contextguard/secrets.py` and append a new tuple to the pattern list:

```python
_SECRET_PATTERNS.append((
    "slack_webhook",                           # Label
    re.compile(r"https://hooks\.slack\.com/services/T\w+/B\w+/\w+"),  # Regex
    0.9,                                       # Severity weight (0.0 to 1.0)
))
```

### Adding a custom pattern at runtime

Users can also supply their own patterns without modifying library source code:

```python
from contextguard import Guard

guard = Guard(custom_secret_patterns=[
    ("internal_api_key", r"MYAPP-KEY-[A-Za-z0-9]{32}", 0.85),
])
```

## Testing Guidelines

- Place all tests in the `tests/` directory following the `test_*.py` naming convention.
- Use pytest fixtures for shared setup and teardown logic.
- Include both positive cases (input should be detected) and negative cases (input should pass cleanly).
- Focus coverage on critical paths: injection detection, secret scanning, and PII identification.

Example test:

```python
def test_detects_slack_webhook(detector):
    result = detector.detect("https://hooks.slack.com/services/T00000/B00000/abc123")
    assert result.is_detected
    assert "slack_webhook" in result.labels
```

## Documentation

- Keep [README.md](README.md) updated whenever a public API changes.
- Add new usage examples to [EXAMPLES.md](EXAMPLES.md).
- Update [CHANGELOG.md](CHANGELOG.md) for every release.
- Write docstrings for all new public functions and classes.

## Release Process (Maintainers)

1. Update the `version` field in `pyproject.toml`.
2. Add a new section to [CHANGELOG.md](CHANGELOG.md) with the changes included in the release.
3. Commit the version bump and changelog update.
4. Create and push a Git tag:
   ```bash
   git tag v0.X.Y
   git push origin v0.X.Y
   ```
5. The GitHub Actions workflow will automatically build and publish to PyPI.

---

If you have questions about any of this, feel free to open a GitHub issue. We are happy to help.
