How to Contribute

This guide covers the complete contribution workflow from initial setup through pull request review. Follow these steps to ensure your contributions are consistent with the project standards and can be reviewed efficiently.

Quick Start

Fork the repository, clone your fork, and set up the development environment:

Fork, clone, and setup
# Fork and clone
git clone https://github.com/YOUR_USERNAME/acp.git
cd acp

# Create a virtual environment
python -m venv venv
source venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Run the test suite to verify your setup
pytest

Prerequisites

You will need Python 3.11 or later, Git, and a GitHub account. For Cloudflare Worker development, Node.js 18+ and Wrangler CLI are also required.

Development Process

Every contribution follows a six-step workflow: find an issue, create a branch, write code, test, commit, and open a pull request.

Step 1: Find or Create an Issue

Before writing code, check the existing issues to see if someone is already working on the same problem. If you plan a large change, create an issue first and wait for maintainer approval before investing significant effort.

  • Check existing issues to avoid duplicate work
  • Create a new issue if one does not exist for your change
  • Wait for maintainer approval on large or architectural changes
  • Small fixes (typos, documentation) can go directly to a PR

Step 2: Create a Branch

Create a descriptive branch from the latest main branch. Use a prefix that indicates the type of change:

Branch naming conventions
# Feature branch
git checkout -b feature/your-feature-name

# Bug fix branch
git checkout -b fix/bug-description

# Documentation branch
git checkout -b docs/what-you-are-documenting

Step 3: Write Your Code

Follow these guidelines when making changes:

  • Write clean, well-documented code
  • Follow the existing code style (see Code Style below)
  • Add tests for all new functionality
  • Update documentation if your change affects user-facing behavior
  • Never commit secrets, API keys, or infrastructure URLs

Step 4: Test Your Changes

Run the full test suite and all linting tools before committing:

Testing and linting commands
# Run all tests
pytest

# Run tests with coverage report
pytest --cov=. --cov-report=html

# Linting
ruff check .

# Code formatting
black .
isort .

# Type checking
mypy .

Step 5: Commit Your Changes

ACP uses Conventional Commits for all commit messages. This enables automatic changelog generation and makes the project history easy to navigate.

Conventional Commit examples
git commit -m "feat: add new axiom validator"
git commit -m "fix: correct D-score calculation"
git commit -m "docs: update API documentation"
git commit -m "test: add coverage for oracle system"
git commit -m "refactor: simplify consensus engine loop"
git commit -m "chore: update dependency versions"
PrefixPurpose
feat:A new feature or capability
fix:A bug fix
docs:Documentation changes only
test:Adding or updating tests
refactor:Code restructuring without behavior change
chore:Build process, dependency updates, maintenance

Step 6: Push and Create a Pull Request

Push your branch to your fork and open a pull request against the upstream main branch:

Push and open PR
git push origin feature/your-feature-name

Then open a Pull Request on GitHub. In the PR description, include:

  • A clear summary of the changes and their purpose
  • A reference to the related issue (e.g., "Closes #42")
  • Any testing you performed beyond the automated suite
  • Screenshots or output examples if applicable

Code Structure

Understanding the repository layout will help you find the right place for your changes:

Repository layout
src/
├── core/           # Core protocol logic
│   ├── metrics.py  # D-score, H_total, C_ij calculations
│   ├── validators.py
│   └── oracles/    # Verification oracles (Math, Hash, Web)
├── engine/         # ConsensusEngine (Fugue, Sonata, Concert)
├── llm/            # LLM provider adapters (OpenAI, Anthropic, OpenRouter)
├── api/            # FastAPI REST endpoints
├── registry/       # Axiom registry (CRUD, DB models, service)
└── consensus/      # Consensus state management
DirectoryWhat belongs here
src/core/Protocol logic: metrics calculations, validators, oracle implementations. Changes here affect consensus behavior.
src/engine/The ConsensusEngine and musical structures (Fugue, Sonata, Concert). Orchestrates the consensus loop.
src/llm/LLM provider adapters. Each provider has its own module. Add new providers here.
src/api/FastAPI route handlers. REST endpoints for consensus, health checks, and WebSocket connections.
src/registry/Axiom registry with SQLAlchemy models. CRUD operations for axiom management.
tests/All test files. Mirror the src/ structure. Every new module should have a corresponding test file.

Code Style

All Python code must pass the following tools before a PR will be reviewed:

ToolPurposeCommand
BlackCode formatting (deterministic, opinionated)black src/ tests/
isortImport sorting (groups and alphabetizes)isort src/ tests/
RuffFast linting (replaces flake8, pyflakes, etc.)ruff check src/ tests/
mypyStatic type checkingmypy src/ --ignore-missing-imports

Run all checks at once

You can run all checks in sequence with a single command:

black src/ tests/ && isort src/ tests/ && ruff check src/ tests/ && mypy src/ --ignore-missing-imports

For JavaScript and TypeScript code (Cloudflare Workers, frontend), use Prettier and ESLint. Documentation should be written in Markdown.

Testing Requirements

All new code must include tests. The project maintains a minimum of 80% code coverage. Tests use pytest and follow these conventions:

  • Write tests for all new code and bug fixes
  • Maintain above 80% code coverage
  • Use pytest fixtures for shared setup
  • Mock all external API calls (LLM providers, databases)
  • Test both success and error paths
  • Use descriptive test function names that explain the expected behavior
Example test
def test_d_score_calculation():
    """D-score should be near zero for highly agreeing responses."""
    responses = ["Paris", "Paris", "paris"]
    d_score = calculate_d_score(responses)
    assert 0 <= d_score <= 1
    assert d_score < 0.1  # High agreement

Coverage enforcement

Pull requests that reduce overall test coverage below 80% will not be merged. Run pytest --cov=. --cov-report=html to generate an HTML coverage report and verify your changes are adequately tested.

Documentation

Keep documentation in sync with code changes:

  • Update README for user-facing changes
  • Add docstrings to all public functions and classes
  • Update API documentation when endpoint behavior changes
  • Keep CHANGELOG.md updated for notable changes

License Agreement

By contributing to ACP, you agree that your contributions will be licensed under the Business Source License 1.1 (BSL 1.1). The license transitions to Apache 2.0 on 2030-04-09. See the LICENSE file in the repository root for full details.

Contributor License Agreement

For significant contributions, you may be asked to sign a Contributor License Agreement (CLA). Both individual and corporate CLAs are available in the legal/ directory.