Skip to content

Latest commit

 

History

History
153 lines (117 loc) · 6.35 KB

File metadata and controls

153 lines (117 loc) · 6.35 KB

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 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 repo are equally valuable.

Development setup

See the Quickstart section in the README for the canonical setup. In short:

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:

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:

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 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 and discussion-templates.md.
  • Confirmed bugs with clean reproduction — open an issue, not a discussion.
  • Security concerns — never post publicly. Follow the coordinated disclosure process in 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 — 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. 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) 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 for the coordinated disclosure process.

Questions