Codexa is offline-first by default. Please do not include private corpus content, absolute local paths, API keys, logs with sensitive passages, or persisted index data in issues, pull requests, screenshots, or patches.
Use GitHub issues for opt-in feedback:
- Bug reports: include the command, sanitized config snippets, expected behavior, actual behavior, and the smallest non-sensitive reproduction you can share.
- Retrieval quality reports: include the query, sanitized expected source names, relevant metrics if available, and whether dense, BM25, rerank, or RAG output looked wrong.
- Feature requests: describe the job you are trying to complete, the workaround you use today, and why local/offline behavior matters for that job.
Keep changes focused. Run the Python pre-finish checks before submitting when the change touches code:
ruff check codexa tests
pyright
python scripts/check_repo_privacy.py
pytest --cov=codexaUpdate TODO.md when you implement or add backlog items.
Line coverage says a line ran, not that a test would notice it changing.
scripts/run_mutation.py mutates one module (comparison flips, and/or
swaps, dropped not, arithmetic swaps, off-by-one constants, True/False
flips) and re-runs a focused set of tests per mutant:
python scripts/run_mutation.py codexa/search/passage_quality.py \
tests/test_mutation_passage_quality_2026_08_03.pyMutants are compiled in memory by the mutation_hook pytest plugin, so a run
never writes a mutated file into the working tree. A survivor is a change the
suite cannot see — either write a test that fails under it, or record why it is
an equivalent mutant in the test module's docstring.
A bare run exits non-zero on any survivor, which is what you want while
writing tests and the wrong signal for a gate — every module keeps some
genuinely equivalent mutants. scripts/mutation_baseline.json records how many
each module is allowed, so a change can be checked for regression instead:
python scripts/run_mutation.py --check codexa/search/passage_quality.py \
tests/test_mutation_passage_quality_2026_08_03.py--check fails only when your change leaves more mutants alive than the
baseline allows. Survivors, not the percentage, is the gated number: adding code
adds mutation sites, so a module can grow while its score dips without anything
having got worse. Once you kill survivors — or document them as equivalent —
lock the gain in:
python scripts/run_mutation.py --update-baseline codexa/search/passage_quality.py \
tests/test_mutation_passage_quality_2026_08_03.pyNever raise a baseline number to make a run pass; that is the one edit the file
does not accept in review. A module absent from the ledger is not gated yet —
--check says so and passes, and adding it is how mutation coverage grows.
Architectural changes should check the decision records in docs/adr/ first — each ADR scopes a functional or non-functional feature (offline posture, pipeline shape, plugin security, cache lifecycle, …) and names what a change in that area must touch. A change that contradicts a recorded decision supersedes it with a new ADR rather than silently diverging. New enrichment ideas register their riskiest assumption in ADR 0002 before implementation.