Thanks for considering a contribution. pm-rag is process-aware retrieval: code-graph indexing plus event-to-symbol mapping. Tests hermetic: no real LLM, no real embedder, no API keys required.
git clone https://github.com/erphq/pm-rag
cd pm-rag
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
ruff check
pytest -qBoth commands must pass before opening a PR.
pm_rag/graph.py- code graph construction and Personalized PageRank.pm_rag/mapping/- event-to-symbol strategies. One file per strategy:regex.py,embedding.py,llm.py, pluscompose.pyfor stacking.pm_rag/eval.py- top-k accuracy and MRR evaluation harness.pm_rag/cli.py- thepm-ragCLI.tests/- pytest, one file per module.
Every external dependency is a function the caller passes in:
EmbedFn = Callable[[list[str]], list[list[float]]]- turn strings into vectors. Tests use a deterministic in-memory embedder.LlmFn = Callable[[str], str]- turn a prompt into a string. Tests use a deterministic fake that returns a recorded JSON array.EventSource- your store of events. Tests useFakeEventSource.
This is the test contract: never reach for a real OpenAI / Anthropic /
local-model client in pm_rag/. If you need one, the caller wires it
in.
- Create
pm_rag/mapping/<strategy>.pyexporting a<strategy>_mapping(events, symbols, ...)function returning adict[event_id, list[symbol_id]]. - If it composes naturally, add an
__all__entry inpm_rag/mapping/__init__.py. - Test with both deterministic input and an empty-events edge case.
- If it has a numeric threshold or top_k, write a test pinning the expected ordering. Hand-trace the algorithm before locking the assertion: for diffusion, embedding similarity, and LLM-rerank, the seed is rarely top-1.
- Python 3.10+. Type hints required on public functions.
- Ruff config in
pyproject.toml. Don't disable rules ad-hoc. - No em dashes in code, comments, or docs.
- Commit messages:
feat(mapping): .../fix(graph): .../docs(...).
Releases are tagged on GitHub. There is no PyPI publish workflow yet.