Skip to content

Commit 8612677

Browse files
docs: update README and CONTRIBUTING for public release
1 parent faf8020 commit 8612677

2 files changed

Lines changed: 276 additions & 65 deletions

File tree

CONTRIBUTING.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Contributing to gateframe
2+
3+
Thank you for your interest in contributing. This document covers how to set up a dev environment, how to add new rule types and integrations, and what the PR process looks like.
4+
5+
---
6+
7+
## Dev setup
8+
9+
```bash
10+
git clone https://github.com/practicalmind-ai/gateframe.git
11+
cd gateframe
12+
pip install -e ".[dev]"
13+
python -m pytest tests/ -v
14+
```
15+
16+
Lint and format:
17+
18+
```bash
19+
ruff check gateframe/ tests/ examples/
20+
ruff format --check .
21+
ruff format .
22+
```
23+
24+
All tests must pass and both checks must be clean before a PR is mergeable.
25+
26+
---
27+
28+
## Project structure
29+
30+
```
31+
gateframe/
32+
├── core/ # ValidationContract, WorkflowContext, FailureMode, EscalationRouter
33+
├── rules/ # StructuralRule, SemanticRule, BoundaryRule, ConfidenceRule
34+
├── integrations/ # OpenAI, Anthropic, LiteLLM, LangChain
35+
├── audit/ # AuditLog, exporters
36+
└── cli/ # inspect, replay subcommands
37+
tests/ # mirrors gateframe/ structure
38+
examples/ # runnable end-to-end examples
39+
```
40+
41+
---
42+
43+
## How to add a new rule type
44+
45+
1. Create `gateframe/rules/<name>.py` with a single class inheriting from `Rule`.
46+
2. Implement `validate(self, output, **context) -> FailureResult | None`. Return `None` on pass.
47+
3. Catch all exceptions inside `validate` — never let them propagate. Return a `FailureResult` with the exception message instead.
48+
4. Choose a default `failure_mode` that fits the severity: `HARD_FAIL` for scope or authority violations, `SOFT_FAIL` for confidence or quality degradation.
49+
5. Write actionable error messages. `"Validation failed"` is not acceptable. `"Confidence 0.42 is below minimum threshold 0.7."` is.
50+
6. Add the class to `gateframe/__init__.py` and the `__all__` list so it is part of the public API.
51+
7. Create `tests/rules/test_<name>.py`. Cover: happy path, failure path, exception handling, custom failure mode, context forwarding, and the default name.
52+
53+
---
54+
55+
## How to add a new integration
56+
57+
1. Create `gateframe/integrations/<provider>.py`.
58+
2. Add a `_require_<provider>()` guard that raises `ImportError` with install instructions if the SDK is not available.
59+
3. Implement `extract_text`, `extract_json`, and `extract_metadata` as standalone functions (not methods). Keeping them separate from the validator class makes them individually testable.
60+
4. Implement a `<Provider>Validator` class that accepts a `ValidationContract` and optional config, and calls the extract functions inside `validate()`.
61+
5. Add the optional dependency to `pyproject.toml` under `[project.optional-dependencies]`.
62+
6. Create `tests/integrations/test_<provider>.py`. Use dataclasses to mock provider responses — no real API calls. Cover all three extract functions and the validator class.
63+
64+
---
65+
66+
## Testing requirements
67+
68+
- Every failure path must be tested, not just the happy path.
69+
- Use dataclasses to mock provider responses, not `unittest.mock` or real API calls.
70+
- Tests mirror the source tree: `gateframe/rules/boundary.py``tests/rules/test_boundary.py`.
71+
- Construction-time errors (e.g. `ValueError` for bad rule configuration) are tested separately from validation failures.
72+
73+
---
74+
75+
## Code style
76+
77+
- No `print` in library code. Use `structlog` for all internal logging.
78+
- No unnecessary docstrings or comments. Code should be self-explanatory.
79+
- Type hints required everywhere. `Any` requires a comment explaining why.
80+
- One class per file where possible.
81+
- Error messages must be actionable — include what failed, the actual value, and the expected value or constraint.
82+
- Python 3.10+. No dependencies in core beyond `pydantic>=2` and `structlog`.
83+
84+
---
85+
86+
## PR process
87+
88+
1. Fork the repository and create a branch from `main`.
89+
2. Make your changes. If you're adding a feature, add tests for it.
90+
3. Run `python -m pytest tests/ -v` — all tests must pass.
91+
4. Run `ruff check gateframe/ tests/ examples/` and `ruff format --check .` — both must be clean.
92+
5. Open a pull request with a description of what the change does and why.
93+
94+
If you're unsure whether a change fits the scope of the project, open an issue first.

0 commit comments

Comments
 (0)