Skip to content

Latest commit

 

History

History
150 lines (107 loc) · 5.08 KB

File metadata and controls

150 lines (107 loc) · 5.08 KB

Contributing to xrag

Thanks for your interest in xrag. This document covers how to get set up, the checks we expect before review, and the conventions the PR template encodes.

1. Getting set up

xrag uses uv for dependency management and requires Python 3.11 or newer.

git clone https://github.com/henryle97/xrag.git
cd xrag
make sync              # uv sync --group dev + the extras the tests need
make precommit-install # installs the pre-commit hooks (recommended)

make sync installs the cli, chroma, and rerank-cohere extras because the unit tests import them directly. A bare uv sync is not enough to run the test suite.

Local PDF/OCR parsing is heavy and optional. Add it only if you're working on that path:

uv sync --group dev --extra cli --extra chroma --extra rerank-cohere \
  --extra parser-unstructured-local-pdf

Environment variables

Copy .env.example to .env and fill in only the keys you need. Every variable maps to a field on xrag.config.settings.Settings. Unit tests are hermetic and need no credentials.

2. Development workflow

Run these before opening a PR:

make lint        # ruff check + ruff format --check
make unit-test   # pytest tests/unit -q — hermetic, this is the CI gate

make check additionally runs compileall. Integration tests (make integration-test) make real network calls, are not part of CI, and require credentials.

After changing runtime behavior, also exercise the changed path with a live CLI command — unit tests alone don't prove a pipeline still runs end to end.

Tests

  • Unit tests live in tests/unit/ and must stay hermetic — no network, no credentials, no reliance on files outside the repo.
  • Contract tests in tests/contract/ run against the built wheel and guard the public API surface. If you add or remove anything in xrag.__all__, update them.
  • Mark network-dependent tests with requires_network, requires_qdrant, or requires_openai.

Public API surface

Everything exported from xrag.__all__ is the supported surface and is SemVer-bound. Anything outside it is internal. Changing an exported name is a breaking change and needs a contract-test update plus a changelog entry.

3. Pull requests

The PR template asks for four things. Keep the shape:

  • Problem — what's broken or missing
  • Why — why it's worth changing now
  • What changed — the actual diff, in prose
  • What did NOT change — scope boundaries, so reviewers know where not to look

Include a Test plan with make lint and make unit-test checked, plus any live CLI, integration, or manual verification you did. Skip the Risks section entirely when there are none rather than writing "None".

Other expectations:

  • Branch from an up-to-date main: git checkout main && git pull --ff-only origin main
  • Keep PRs focused. Parent/child issues ship together as the parent's PR.
  • Resolve review threads only after the fix is pushed.
  • Don't auto-merge.

3.1 Closing issues

GitHub's auto-close parser only fires when a close keyword (Closes, Fixes, Resolves) sits on the same content line as the issue reference. A heading like ## Closes followed by #19, #20, #21 silently closes nothing.

Write one close keyword per issue, each on its own content line:

Closes #19. Closes #20. Closes #21.

Verify before merging:

gh pr view <N> --json closingIssuesReferences

4. Commit conventions

We use Conventional Commits with a module scope:

feat(parser): add DocxPicturePartitioner
fix(config): reject unknown provider names
test(chunker): cover image chunk emission
docs(plans): refresh indexing backlog

Common scopes: parser, chunker, embedder, indexer, client, config, eval, ci, packaging.

5. Architecture decisions

Check docs/adr/ before making architectural changes — it records decisions that are easy to accidentally reverse. Add a new ADR when you change a cross-module contract or reverse an existing decision.

Deeper domain context lives in CONTEXT.md and docs/agents/domain.md.

6. Evaluation and benchmarks

Retrieval quality changes need evidence. The full discipline is documented in CLAUDE.md; the short version:

  • Run evals through scripts/eval/, which writes to experiments/eval/<config-stem>-<timestamp>/.
  • Append a new row to docs/BENCHMARK.md — never edit existing rows.
  • Per-category R@10 is the primary regression signal.
  • experiments/eval/experiments.jsonl is the append-only source of truth.

Benchmark documentation uses a fictional issuer and synthetic figures. Never commit real customer documents, real financial data, or anything under data/ (it is gitignored for this reason).

7. Reporting bugs and requesting features

Use the issue templates. For security issues, follow SECURITY.md instead of opening a public issue.