Contributing¶
Setup¶
git clone https://github.com/Rohithmatham12/ContextOS
cd ContextOS
python -m venv .venv
source .venv/bin/activate # macOS / Linux
.venv\Scripts\activate # Windows
pip install -e ".[dev]"
Verify the setup:
Running Tests¶
# All tests
pytest
# With coverage report
pytest --cov=contextos --cov-report=term-missing
# Single module
pytest tests/core/test_context_selector.py
# Single test
pytest tests/core/test_secret_detector.py::TestDetectOpenAIKey -v
Coverage gate: 80% minimum. PRs that drop coverage below this will not be merged.
Linting and Formatting¶
# Check for lint errors
ruff check contextos/ tests/
# Auto-fix safe issues
ruff check --fix contextos/ tests/
# Format
ruff format contextos/ tests/
# Type check
mypy contextos/
All four must pass cleanly before opening a PR.
Project Conventions¶
Code Style¶
- Line limit: 100 characters (enforced by ruff)
- No comments explaining what the code does — well-named identifiers do that
- Comments only for non-obvious invariants, constraints, or workarounds
- No docstrings on internal helpers; public API only
pathlib.Patheverywhere — noos.path, no string concatenation for paths
Optional Imports¶
All optional dependencies must be lazy-imported inside functions:
# Correct
def count_tokens(text: str) -> int:
try:
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
return len(enc.encode(text))
except ImportError:
return len(text) // 4
# Wrong — breaks installs without tiktoken
import tiktoken
This rule applies to: tiktoken, headroom_ai, tree_sitter.
Determinism¶
ContextOS produces byte-identical output for identical inputs. Any change that breaks this is a regression. Use sorted() whenever iterating over directory contents.
Secret Safety¶
Never add real credentials or API keys to fixtures, tests, or documentation. Use obviously fake values (e.g., fake-api-key-for-testing). For test patterns that need to match real token formats, construct them dynamically from parts — never as a single literal string that would trigger push protection.
# Correct — dynamic construction
_XOXB = "xoxb-" + "1" * 12 + "-" + "1" * 12 + "-" + "a" * 24
# Wrong — literal token triggers GitHub push protection
_XOXB = "xoxb-<12digits>-<12digits>-<24chars>" # don't write as a real-looking literal
Fixture Repos¶
Fixture repos in tests/fixtures/ are real directories with real files — not mocked. Keep them minimal. Never add synthetic data that looks like a real credential.
Adding a Feature¶
New Exporter¶
- Create
contextos/exporters/<name>.pysubclassing the base pattern inexporters/base.py - Define
FILENAME,TOOL_NAME,USAGE_NOTE,_INSTRUCTIONS - Register the tool name in
contextos/cli/commands/export.py - Add tests in
tests/exporters/test_<name>.py - Document in the README export table and
docs/USAGE.md
New Secret Pattern¶
- Add the regex to
_CONTENT_PATTERNSincontextos/core/secret_detector.py - Add a corresponding test class in
tests/core/test_secret_detector.pyfollowing the existing pattern - Update the pattern table in
docs/SAFETY.md
New CLI Command¶
- Create
contextos/cli/commands/<command>.pywith a Typer sub-app - Register in
contextos/cli/main.py - Add tests in
tests/cli/test_<command>.py - Document in
docs/USAGE.mdand README CLI reference
Pull Request Process¶
- Branch from
master:git checkout -b feature/<short-description> - Write tests first (or alongside) — PRs without tests for new functionality will not be merged
- All tests pass, all lint checks pass, coverage does not drop
- PR title: short and specific (
Add Stripe pattern to secret detector) - PR body: what changed and why — not a blow-by-blow of implementation details
Keep PRs focused. A PR that adds a feature and refactors unrelated code is harder to review and slower to merge. Split them.
Reporting Bugs¶
Open an issue at https://github.com/Rohithmatham12/ContextOS/issues.
Include:
- ContextOS version (contextos --version)
- Python version (python --version)
- Operating system
- Minimal command that reproduces the issue
- Expected vs actual output
For secret detection issues: sanitize the example — replace the real credential with a fake one before posting.
Non-Goals¶
To keep PRs in scope, here is what ContextOS deliberately does not do:
- No cloud storage or context sharing
- No executing repo code during analysis
- No LLM calls during context selection (by default)
- No embedding-based ranking (until v1.0, opt-in only)
- No telemetry or analytics
- No paid features
If your contribution requires a network call, an external service, or storing data outside .contextos/, it needs a very clear opt-in flag and thorough discussion before implementation.