# Contributing to Statewave

Thanks for your interest in contributing — Statewave is built in the open and
external contributions are very welcome.

This document covers the contribution process and the licensing implications
of contributing to an Apache-2.0-licensed project.

## Ways to contribute

- **Bug reports** — open a [GitHub issue](https://github.com/smaramwbc/statewave/issues)
  with reproduction steps, expected vs. actual behavior, and version info.
- **Feature requests** — open an issue describing the use case and the
  problem you are trying to solve. Concrete use cases beat abstract feature
  ideas.
- **Pull requests** — see "Pull request process" below.
- **Documentation** — improvements to the [statewave-docs](https://github.com/smaramwbc/statewave-docs)
  repo are equally valuable.

## Development setup

See the [Quickstart](README.md#quickstart) section in the README for the
canonical setup. In short:

```bash
docker compose up db -d
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,llm]"
alembic upgrade head
pytest tests/ -v
```

Please run `ruff` and the test suite locally before opening a PR.

## Verifying a cold install

To validate the full fresh-user path (wipe volumes → compose up → readiness → smoke
checks), use the root Makefile target:

```bash
cp .env.example .env   # if you have not already
pip install -e ".[dev]"
make test-cold
```

`make test-cold` will:

1. `docker compose down -v` (wipe persisted state)
2. `docker compose up -d`
3. Poll `GET /readyz` until `status` is `ready` (60s timeout by default)
4. Run the smoke suite: `pytest tests/smoke/ -m smoke`
5. Print **time-to-first-ready** in seconds

Override defaults if needed:

```bash
API_URL=http://127.0.0.1:8100 READYZ_TIMEOUT=90 make test-cold
```

Requires Docker, `curl`, and Python dev dependencies (`httpx`, `pytest`).

## Discussing changes before opening a PR

Use the lightest-weight venue that fits the change:

- **Small, obvious fixes** — typos, doc tweaks, isolated bug fixes — go straight
  to a PR. No discussion needed.
- **Larger features, behavior changes, new endpoints** — start in
  [GitHub Discussions](https://github.com/smaramwbc/statewave/discussions)
  under **Ideas & Feature Requests** with the use case and proposed shape, so
  we can align before you invest in code.
- **Architecture changes, API shape changes, storage / security / integration
  designs** — open an **RFC** in Discussions. The RFC template and process are
  documented in [statewave-docs/community/discussions.md](https://github.com/smaramwbc/statewave-docs/blob/main/community/discussions.md)
  and [discussion-templates.md](https://github.com/smaramwbc/statewave-docs/blob/main/community/discussion-templates.md).
- **Confirmed bugs with clean reproduction** — open an
  [issue](https://github.com/smaramwbc/statewave/issues), not a discussion.
- **Security concerns** — never post publicly. Follow the coordinated
  disclosure process in [SECURITY.md](SECURITY.md).
- **Licensing questions** — general questions ("how does Apache-2.0 apply
  to my use case?") are welcome publicly in Discussions. Enterprise support
  contracts (SLA, indemnity, procurement) go privately to
  [licensing@statewave.ai](mailto:licensing@statewave.ai) — these are
  services agreements, not separate licenses. Apache-2.0 covers the code.

Rule of thumb: if you can describe a clean reproduction or a concrete change,
open an Issue or PR. Otherwise, start in Discussions.

## Pull request process

1. **Open an issue or discussion first** for non-trivial changes so we can
   align on approach before you invest in code.
2. **Branch from `main`**, keep PRs focused, and prefer small commits with
   clear messages.
3. **Add tests** for new behavior. Statewave is infrastructure — coverage
   matters more than feature volume.
4. **Update docs** if you change public API, configuration, or behavior.
5. **Pass CI** — lint, type checks, and tests must be green.
6. **Describe the change** in the PR body: motivation, approach, and any
   tradeoffs considered.

## Licensing of contributions

Statewave is licensed under the [Apache License, Version 2.0](LICENSE).
By contributing — opening a pull request, sending a patch, or otherwise
submitting work — you agree that your contribution is licensed under
Apache-2.0 along with the rest of the project. You retain copyright in
your work.

We use the **Developer Certificate of Origin** ([DCO](https://developercertificate.org/))
for contributions. Sign your commits with `git commit -s` (or `--signoff`)
to add a `Signed-off-by:` trailer asserting that you have the right to
contribute the work under the project's license.

If your employer has rights to your work, please make sure they have
authorized the contribution before submitting.

## Code style

- Python 3.11+, formatted with `ruff` (settings in `pyproject.toml`).
- Type hints on public APIs.
- Match the surrounding code's conventions; prefer small, composable
  functions; prefer clear names over comments.

## Invariants enforced by CI

A few cross-cutting rules are checked automatically so a single change can't
silently reintroduce a whole class of bug. If your PR trips one of these, the
fix is to satisfy the rule (not to weaken the test):

- **Tenant scoping** — every repository query that takes a `subject_id` must
  also take a `tenant_id` and apply `_tenant_filter`, so it can't read across
  tenants. (`tests/test_tenant_scoping_invariant.py`)
- **Bounded pagination** — every `limit` query parameter needs `ge` and `le`,
  and every `offset` needs `ge`. (`tests/test_route_limits_invariant.py`)
- **One tokenizer** — lexical word comparison goes through
  `server.services.tokenization.tokenize`; raw `.lower().split()` elsewhere is
  rejected, because punctuation welded onto tokens silently zeros overlap.
  (`tests/test_no_raw_tokenization.py`, `tests/test_tokenization.py`)

Each rule exists because a real bug shipped without it; the test is the cheapest
place to catch the next one.

## Reporting security issues

Please **do not** open a public issue for security vulnerabilities. See
[SECURITY.md](SECURITY.md) for the coordinated disclosure process.

## Questions

- General questions: [GitHub Discussions](https://github.com/smaramwbc/statewave/discussions)
- Licensing questions: [licensing@statewave.ai](mailto:licensing@statewave.ai)
- Security: [security@statewave.ai](mailto:security@statewave.ai)
