Thank you for contributing. This document covers everything you need to get started.
cMCP is a hardware-attested policy gateway. Changes to the TEE boundary, signing path, audit chain, or TRACE Claim generation require extra care: these are security-critical components. When in doubt, open an issue first.
Use agents. A lot of this was built with them and saying otherwise would be dishonest.
The rule is that you have to understand what you submit. If you cannot explain what your change does and how it interacts with the rest of the system, with the agent closed, do not open the pull request. Reviewing a change nobody can explain costs more than writing it did, and it becomes someone else's problem the moment it merges.
That is a rule about understanding, not about tooling.
If you have not contributed here before, ask before you build. Open an issue saying what you want to change and why, in your own words. A maintainer will reply and add you with /vouch, and after that your pull requests go through the normal review.
A pull request from an account that has not been vouched is closed automatically, with a comment pointing back here. That is not a judgement about you or about the change. It exists because agent-written contributions are cheap to produce and expensive to review, and a short conversation first is better for both sides than a review neither of us can finish.
Anyone who can already push, and anyone with a merged pull request here before this rule existed, is already vouched.
All commits must include a Signed-off-by line. This is a lightweight way to certify you wrote the code or have the right to contribute it. No CLA required.
git commit -s -m "feat: your change"
The sign-off certifies the Developer Certificate of Origin v1.1.
Requires Python 3.11+.
git clone https://github.com/agentrust-io/cmcp
cd cmcp
pip install -e ".[dev]"ruff check src/ tests/ # lint
mypy src/cmcp_gateway/ # type check
bandit -r src/ -c pyproject.toml # security scan
pytest tests/unit/ -v # unit testsAll four must pass before a PR is mergeable.
The PyPI workflow installs the exact wheel and source distribution into separate
clean environments before upload. It checks release-tag/version agreement,
metadata and runtime versions, import provenance outside the checkout, core
configuration construction, and the installed cmcp console entry point.
The release container uses a multi-stage build: the builder creates a wheelhouse
from production dependencies only, while the runtime installs it offline and
runs as numeric UID/GID 10001. Do not add editable installs, the dev extra, or
root execution to the runtime stage.
Dockerfile, schema, and container-workflow pull requests build the image without
registry credentials or a push; publishing, signing, and provenance attestation
remain restricted to version tags.
Follow Conventional Commits:
feat: add sev-snp provider
fix: correct nonce encoding in RuntimeInfo
docs: clarify TRACE profile envelope structure
test: add coverage for stale attestation path
refactor: extract _build_policy helper
Keep commits small and focused. One logical change per commit. Do not bundle unrelated fixes.
- Branch from
main:git checkout -b feat/your-change - Write tests for new behaviour: the test suite must pass
- Run all four checks locally (see above)
- Open a PR against
mainwith the template filled in - At least one maintainer must approve before merge
- Squash if the commit history is noisy; preserve meaningful commits
Changes to these paths require two maintainer approvals and a comment explaining the security impact:
src/cmcp_gateway/audit/: signing, audit chain, TRACE Claim generationsrc/cmcp_gateway/tee/: TEE provider integrationsrc/cmcp_gateway/policy/: Cedar policy evaluation
Do not open a public issue. Use GitHub Security Advisories for private disclosure. See SECURITY.md.
- Python 3.11+ syntax throughout (
X | Y,match, etc.) ruffenforces style; do not add# noqawithout a comment explaining whymypy --strictonsrc/cmcp_gateway/; new public functions need type annotations- No comments that describe what the code does: only why when non-obvious
- Tests live in
tests/unit/and follow the existingtest_<module>.pynaming
Open a GitHub Discussion for design questions or proposals before writing code.