Development

Architecture

The public API is intentionally small: fetch_evidence() accepts a query and returns normalized, deduplicated Evidence results. Provider-specific HTTP requests, credential handling, and response parsing live behind an internal Brave Search provider. The provider depends on a small HTTP client protocol, so tests and future integrations can inject a mock client instead of using the network.

Candidate retrieval and local relevance ranking are separate steps. Brave Search retrieves candidate evidence from the web; a replaceable local ranker then orders those candidates against the original query. The default ranker is a small standard-library TF-IDF implementation over evidence titles and snippets.

Feedback-aware reranking is available through the Python/domain layer. A SearchSession retains the original query, candidate evidence, current ranked results, and accumulated RelevanceFeedback entries keyed by evidence URL. The TF-IDF ranker applies a lightweight Rocchio-style query update: it keeps the original query vector, moves it toward evidence marked MORE or RELEVANT, moves it away from evidence marked LESS or IRRELEVANT, and records UNSURE without changing ranking.

Feedback-informed retrieval expansion is separate from local reranking. The default query refiner tokenizes the original query and feedback-marked evidence, removes small stop words, scores candidate expansion terms lexically with TF-IDF, avoids duplicating original query terms, suppresses terms associated mainly with irrelevant evidence, and appends up to four useful terms. The refined query is printed before each expand retrieval.

Only Brave Search is implemented in this slice. No persistence or additional search providers are included yet.

Local checks

Create or update the local development environment:

uv sync

Run the common checks:

uv run pytest
uv run ruff check .
uv run mypy src
uv build

Build documentation into docs/built/:

uv run sphinx-build -b html docs/source docs/built

The same commands are available through the top-level Makefile:

make check
make docs