# Contributing to Local Deep Research

Thank you for your interest in contributing to Local Deep Research.

We deeply value every contribution to this project. Open source thrives when developers share their expertise, creativity, and passion. Whether you're fixing a typo, optimizing performance, adding a feature, or helping with documentation — your work directly impacts researchers and developers worldwide. Code contributions are not the only way to help: answering questions, reporting bugs, and improving documentation are equally valuable. We carefully review all PRs and are genuinely excited to merge contributions that enhance the project. This is truly a community-driven project, and we're honored to have you join us.

### Before You Start

**Please keep PRs small and atomic.** One fix, one feature, one change per PR. This repository has grown in complexity, and large or cross-cutting PRs become very difficult to review safely. Small, focused PRs are easier to review, faster to merge, and less likely to introduce regressions. If your change touches multiple concerns, split it into separate PRs — this protects your time as much as ours.

**Talk to us before building large changes.** Open an issue, start a discussion, or drop a message on [Discord](https://discord.gg/ttcqQeFcJ3). This helps us reach agreement on your approach before you put significant effort into it. For small fixes (typos, bugs with obvious solutions), feel free to open a PR directly. For anything larger, a quick comment like this goes a long way:

> "I'd like to work on this. My intended approach would be to [brief description]. Does this align with what you'd expect?"

**Don't hesitate to ask questions.** A lot of people worry about "wasting the team's time," but we genuinely don't feel that way — contributors are important to us. Both core team members and external contributors go through the same review process, and review feedback is completely normal (it happens to our core contributors too).

## 📚 Developer Resources

For detailed development setup instructions, please see our [Developer Guide](https://github.com/LearningCircuit/local-deep-research/wiki/Developer-Guide) which covers:
- Environment configuration with PDM
- Pre-commit hooks setup
- Building packages
- Running the application

## 🔒 Security Guidelines

As a public repository, we maintain strict file management policies to ensure code quality and prevent unintended data exposure.

### Allowed File Types

Our repository uses a whitelist approach. Only these file types are permitted:
- **Source code**: `.py`, `.js`, `.html`, `.css`
- **Configuration**: `.json`, `.yml`, `.yaml`, `.cfg`
- **Documentation**: `.md`, `.ipynb`
- **Project files**: `LICENSE`, `README`, `README.md`, `Dockerfile`, `pyproject.toml`, etc.
- **Scripts**: `.sh`, `.template`
- **Windows installers** (only in `installers/` directory): `.bat`, `.ps1`, `.iss`, `.ico`

### Blocked File Types

The following are automatically blocked by our CI/CD pipeline:
- Data files (`.csv`, `.xlsx`, `.jsonl`, `.db`, `.sqlite`, `.parquet`, etc.)
- Binary files (`.pickle`, `.pkl`, `.npy`, `.npz`)
- Media files (`.mp4`, `.png`, `.jpg`, `.pdf`, etc.)
- Archive files (`.zip`, `.tar.gz`, `.rar`)
- Sensitive files (`.env`, `.key`, `.pem`, or files containing credentials)
- Files larger than 1MB

## 🚀 Quick Start

1. **Fork and clone the repository**
2. **Set up your development environment** following the [Developer Guide](https://github.com/LearningCircuit/local-deep-research/wiki/Developer-Guide)
3. **Install pre-commit hooks**:
   ```bash
   pre-commit install
   pre-commit install-hooks
   ```
4. **Create a new branch** for your feature or fix

## 💻 Development Workflow

### Configuration

Never commit sensitive information like API keys or passwords. Configuration is typically done through the web UI.

For environment variables and advanced configuration, see the [Installation guide](https://github.com/LearningCircuit/local-deep-research/wiki/Installation#environment-variables) on our wiki.

### Testing

Run tests before submitting PRs:
```bash
pdm run python run_tests.py
```

#### No shadow tests

A test must exercise real production code. A **shadow test** imports nothing
from `local_deep_research` and instead asserts on an inline reimplementation,
pure stdlib behaviour, or a locally-built dict — it inflates the test count and
coverage while catching zero regressions. The `check-shadow-tests` pre-commit
hook blocks any `test_*.py` module that never imports the package.

If a test legitimately has no SUT import — e.g. a black-box HTTP test driven
through the Flask client, a meta-test for a pre-commit hook, or a guardian test
that asserts on repository structure — exempt it with a self-documenting marker:

```python
# allow: no-sut-import — black-box API test, exercises the app via the Flask client
```

The reason after the marker is required. Whole black-box/meta test trees
(`tests/api_tests/`, `tests/ui_tests/`, `tests/hooks/`, …) are excluded in
`.pre-commit-config.yaml`.

### Code Quality

Pre-commit hooks will automatically:
- Lint and auto-fix with Ruff (`ruff --fix`)
- Format code with Ruff (`ruff format`)
- Detect secrets with gitleaks
- Lint shell scripts with shellcheck
- Lint JavaScript with ESLint
- Check for large files and case conflicts
- Run custom checks (datetime timezone, session context managers, SSRF protection, etc.)

## 📋 Pull Request Process

1. **Search first** — Check existing PRs and issues to make sure nobody is already working on the same thing
2. **Comment before you code** — If you're picking up an issue, leave a comment so others don't duplicate your effort
3. **Create a focused PR** — One feature/fix per PR. If your PR is large or cross-cutting, consider splitting it
4. **Write clear commit messages** — Explain what and why, not just what changed
5. **Add tests** — Include tests for new functionality
6. **Update documentation** — Keep docs in sync with code changes
7. **Add a release-notes fragment** — If your change is user-visible (new feature, bug fix, breaking change, security fix, etc.), drop a one-line markdown file at `changelog.d/<PR-number>.<category>.md` where `<category>` is one of `breaking`, `security`, `feature`, `bugfix`, `removal`, `misc`. The pre-commit hook will nudge you if you forget. See [`changelog.d/README.md`](changelog.d/README.md) for the convention. Skip for dep bumps, CI tweaks, and pure refactors — the auto-generated PR list catches those.
8. **Ensure CI passes** — All automated checks must pass. Address CI failures promptly

We will review your pull request and either merge it, request changes, or close it with an explanation. Don't worry about things like commit message formatting — we squash-merge and can adjust the final message.

### Pull Request Lifecycle

We use a small set of labels to make PR triage transparent. They're auto-applied by `.github/workflows/pr-triage.yml`:

| Label | What it means for you |
|-------|----------------------|
| `needs-codeowner-review` | Your PR is in the queue for first review by a global codeowner |
| `awaiting-author` | A codeowner asked for changes — please respond when you can |
| `awaiting-codeowner` | You've responded; a codeowner will re-review |
| `needs-rework` | The PR needs a substantive next step (e.g., split into smaller PRs, fix tests, address scope) before line-by-line review is useful |

For maintainer-side details — search filters, escalation paths, and how reviewers handle low-engagement PRs — see [`docs/processes/review-process/`](docs/processes/review-process/).

### Showing your engagement

AI tooling is welcome — we use it too. What helps reviewers most is seeing that you've engaged with the change. The simplest ways to make that visible:

- **Describe what you tested by hand** in your PR body. "CI is green" only tells us the test runner ran — a sentence or two on what you actually exercised goes a long way.
- **Keep the PR focused on a single logical change** so it can be reviewed in one pass.
- **Respond to review questions directly** — if a reviewer asks why X, answer about X rather than re-generating a fresh patch.

If a PR has signals that engagement may be missing (broken tests on the branch, large mechanical churn across many files, unrelated changes bundled together), we may apply `needs-rework` and ask for substantive revision before reviewing line-by-line. The label is about focusing review time effectively, not about turning the contribution away — once the foundation is in place, we'll give it real attention.

### Security Checks

Every PR automatically runs:
- File whitelist enforcement
- Large file detection (>1MB)
- Security pattern scanning
- Binary file detection

## 🛡️ Additional Security

### GitGuardian

For enhanced security on your fork:
1. Visit [GitGuardian on GitHub Marketplace](https://github.com/marketplace/gitguardian)
2. Install the free plan for public repositories
3. It will scan commits for exposed secrets

### If You Accidentally Commit Sensitive Data

1. **Immediately revoke** any exposed credentials
2. **Clean git history** using BFG Repo-Cleaner or git filter-branch
3. **Force push** the cleaned history
4. **Notify maintainers** if the data was pushed to the main repository

## 🤝 Community

- **Discord**: Join our [Discord server](https://discord.gg/ttcqQeFcJ3) for discussions
- **Issues**: Check existing issues before opening new ones
- **Wiki**: Contribute to our [documentation wiki](https://github.com/LearningCircuit/local-deep-research/wiki)

## 📝 Code of Conduct

- Be respectful and professional
- Welcome newcomers with patience
- Focus on constructive feedback
- Report inappropriate behavior to maintainers

## 🏆 Recognition

All contributors are recognized in:
- Release notes
- GitHub contributors graph
- Special mentions for significant contributions

Thank you for helping improve Local Deep Research! 🎉
