Contributing to ExecutionKit¶
ExecutionKit is a minimal library — keep changes focused and test-first.
Dev Setup¶
git clone https://github.com/tafreeman/executionkit.git
cd executionkit
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
Verify the install:
Pre-commit hooks¶
Install once after cloning:
Hooks run automatically on git commit. What they check:
| Hook | Purpose |
|---|---|
ruff |
Lint + auto-fix (E, F, W, I, N, UP, S, B, A, C4, SIM, TCH, RUF) |
ruff-format |
Consistent formatting |
mypy --strict |
Full type checking |
detect-private-key |
Block accidental key commits |
check-merge-conflict |
Block conflict markers |
end-of-file-fixer |
Ensure newline at EOF |
trailing-whitespace |
Strip trailing spaces |
To run hooks manually without committing:
Running the Test Suite¶
# Unit tests and deterministic smoke tests — no real API calls
python -m pytest
# With coverage report — must stay above 80%
python -m pytest --cov=executionkit --cov-fail-under=80
Coverage is enforced in CI via fail_under = 80 in pyproject.toml. New code
must include tests — follow TDD: write the test first (RED), implement to pass
(GREEN), then refactor (IMPROVE).
Use MockProvider from executionkit._mock in tests. The public test suite is
deterministic and does not call live LLM APIs; add a separately documented
manual smoke script before introducing provider-backed tests.
Code Quality¶
Run these before every commit (or let pre-commit do it):
All three must pass. CI blocks on any failure. Bandit (bandit -r executionkit/)
also runs in CI for security scanning.
Style rules¶
Immutability. All value types are @dataclass(frozen=True, slots=True).
Never mutate an existing object; return a new one.
Type hints required. Every function signature and class attribute must be
annotated. mypy --strict is enforced. Avoid Any without justification.
Functions under 50 lines. Decompose larger functions unless readability clearly suffers.
No magic numbers. Use RetryConfig and ConvergenceDetector for tunable
parameters; extract other constants.
Architecture¶
See docs/architecture.md for the full module map,
data-flow diagram, immutability contract, error hierarchy, and extension points.
Key modules:
| Module | Role |
|---|---|
provider.py |
LLMProvider protocol, Provider class, error hierarchy |
types.py |
Frozen value types (PatternResult, TokenUsage, Tool) |
patterns/ |
consensus, refine_loop, react_loop |
engine/ |
ConvergenceDetector, retry, parallel, JSON extraction |
compose.py |
pipe() composition |
kit.py |
Kit session facade |
Commit Convention¶
Use Conventional Commits:
Types: feat, fix, docs, refactor, test, chore, perf, ci
Examples:
feat(patterns): add tree_of_thought pattern
fix(consensus): handle unanimous tie correctly
docs: add react_loop example
test(refine_loop): cover early convergence path
PR Process¶
- Branch from
mainusing afeature/,fix/,docs/, orchore/prefix. - Write tests first (RED → GREEN → IMPROVE).
- Ensure
ruff check .,mypy --strict executionkit/, andpytest --cov-fail-under=80all pass. - Open a PR describing what changed, why, and how to verify.
- One approval required before merge.
PRs should stay under 400 lines of diff. For larger changes, open an issue first to discuss scope.
Security¶
See Security for the full security policy, including the vulnerability reporting process and response SLAs.
Key rules for contributors:
- Never commit API keys, tokens, or
.envfiles. - All examples must read credentials from environment variables.
- Bandit runs in CI — do not add blanket
# noqa: Ssuppressions without discussion. - LLM output is untrusted. See the security doc for prompt injection and tool execution guidance.
Anti-Scope¶
ExecutionKit is a pattern library, not a framework. Reject changes that add:
- Dashboard, routing, or spend-tracking UI
- Stateful graph runtimes or durable execution
- Native provider adapters beyond the OpenAI-compatible format
- Multi-agent handoff or orchestration primitives
If in doubt, open an issue before writing code.
Support¶
Open a GitHub issue. Tag it question for support, bug for defects,
enhancement for feature requests.
Development Provenance & Verification¶
This repository is built solo with AI-assisted tooling. Because there is no second human reviewer, correctness is gated by automated evidence, not peer sign-off:
- CI gates (every push / PR): ruff, ruff-format,
mypy --strict,pytest --cov-fail-under=80, Bandit, and pip-audit (2-OS × 3-Python matrix). Merges block on a red pipeline. - Behavioral verification: the deterministic golden suite and the model-failure corpus (
tests/test_eval_goldens.py,tests/test_eval_failure_corpus.py) run in normal CI and assert output correctness, not just coverage. - Provenance: AI-assisted changes are verified against these gates before merge; the CI and evaluation output is the verification artifact of record.
Contributions are welcome via PR; CI must pass and changes should add or update tests.