Contributing¶
Contributions are welcome — bug fixes, new strategies, integration adapters, docs improvements.
Setup¶
This installs the core library, sidecar, MCP server, and all dev dependencies into a single virtual environment.
Project layout¶
saalis/
├── src/saalis/ ← core library
│ ├── models.py ← all Pydantic models
│ ├── strategy.py ← Strategy ABC + built-in strategies
│ ├── arbitrator.py ← Arbitrator orchestration
│ ├── policy.py ← PolicyEngine + built-in rules
│ ├── wiring.py ← build_arbitrator() factory
│ └── audit/ ← AuditStore implementations
│ ├── base.py
│ ├── jsonl.py
│ └── sqlite.py
│ └── integrations/ ← framework adapters
│ ├── langgraph.py
│ └── crewai.py
├── tests/ ← core library tests
├── sidecar/ ← HTTP REST transport
│ ├── src/saalis_sidecar/
│ └── tests/
├── mcp/ ← MCP transport
│ ├── src/saalis_mcp/
│ └── tests/
└── examples/ ← runnable demos
Before submitting a PR¶
All checks must pass. CI runs the same suite on Python 3.11 and 3.12.
Individual targets:
make test # lib tests with coverage
make test-sidecar # sidecar tests
make test-mcp # MCP tests
make lint # ruff on lib
make typecheck # mypy on lib
make fmt # auto-format everything
Adding a strategy¶
- Subclass
Strategyinsrc/saalis/strategy.py - Implement
name: str(class attribute) andasync def resolve(decision) -> Verdict - Add the strategy to
build_strategy()insrc/saalis/wiring.pyso it's available viabuild_arbitrator()and both transports - Add tests in
tests/ - Export from
src/saalis/__init__.pyif it should be part of the public API - Document in Strategies
Adding a policy rule¶
- Subclass
PolicyRuleinsrc/saalis/policy.py - Implement
check_preand/orcheck_post— returnNoneto pass,PolicyDecision(allowed=False, ...)to block - Add tests in
tests/ - Document in Policy Enforcement
Adding an integration adapter¶
- Create
src/saalis/integrations/<framework>.py - Duck-type the framework's tool/node interface — do not import the framework itself
- Add tests in
tests/test_<framework>_adapter.py - Export from
src/saalis/integrations/__init__.py - Document in
docs/integrations/<framework>.mdand add tomkdocs.ymlnav
Code style¶
- No comments unless the why is non-obvious (a hidden constraint, a known bug workaround)
- No docstrings on simple methods where the name says it all
rufffor formatting and linting —make fmtfixes everything automaticallymypy --strictmust pass — annotate all public functions
Versioning¶
Bump the version in pyproject.toml (root, sidecar/, and mcp/) before merging. Follow semantic versioning:
- patch — bug fixes, no API changes
- minor — new features, backwards-compatible
Merging to main automatically publishes to PyPI if the version is new.
Reporting issues¶
Open an issue at github.com/ulhaqi12/saalis/issues.