Created docs/development/contributor-guide.md with comprehensive practical workflow guidance covering prerequisites, fork/clone workflow, branch naming, commit format, pre-commit hooks, test suite, BDD test writing, code style, type checking, ADR process, PR checklist, and review process. Extended README.md Documentation section with a Documentation Index table linking all major documentation resources. All existing README content preserved intact.
19 KiB
Contributor Guide
This guide walks you through the practical day-to-day workflow for contributing to CleverAgents Core. It complements CONTRIBUTING.md (which defines the rules and standards) by focusing on the how — concrete commands, conventions, and checklists you need to get from idea to merged PR.
New here? Start with CONTRIBUTING.md to understand the project's philosophy, then return here for the step-by-step workflow.
Table of Contents
- Prerequisites and Environment Setup
- Fork and Clone Workflow
- Branch Naming Conventions
- Commit Message Format
- Pre-commit Hooks
- Running the Test Suite
- Writing New Tests
- Code Style
- Type Checking
- ADR Process
- PR Submission Checklist
- Review Process
- Further Reading
Prerequisites and Environment Setup
System Requirements
| Tool | Minimum Version | Notes |
|---|---|---|
| Python | 3.13 | Required; the CI pipeline targets 3.13 |
| Git | 2.40+ | For git add -p interactive staging support |
| Node.js | 18+ | Only needed for Commitizen (npm install -g) |
| Docker | 24+ | Optional; needed for integration tests and Helm |
Initial Setup
# 1. Clone your fork (see Fork and Clone Workflow below)
git clone https://git.cleverthis.com/<your-username>/cleveragents-core.git
cd cleveragents-core
# 2. Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # Linux / macOS
# .venv\Scripts\activate # Windows
# 3. Install all development dependencies
pip install -e ".[dev,tests,docs,tui]"
# 4. Run the setup script — installs pre-commit hooks and verifies tooling
bash scripts/setup-dev.sh
# 5. Verify the CLI works
agents --help
agents --version
# 6. (Optional) Install Commitizen for interactive commit messages
npm install -g commitizen@2.8.6 cz-customizable@4.0.0
Environment Variables
For local development you do not need a real LLM API key. The test suite uses a mock provider automatically:
export CLEVERAGENTS_TESTING_USE_MOCK_AI=true
For LangSmith tracing (optional):
export CLEVERAGENTS_LANGSMITH_ENABLED=true
export CLEVERAGENTS_LANGSMITH_PROJECT=my-dev-project
export CLEVERAGENTS_LANGSMITH_API_KEY=<your-key>
Fork and Clone Workflow
CleverAgents uses a fork-and-branch model. All contributions come through a personal fork, never by pushing directly to the upstream repository.
# 1. Fork the repository on Forgejo (click "Fork" in the UI)
# 2. Clone your fork
git clone https://git.cleverthis.com/<your-username>/cleveragents-core.git
cd cleveragents-core
# 3. Add the upstream remote so you can pull in future changes
git remote add upstream https://git.cleverthis.com/cleveragents/cleveragents-core.git
# 4. Verify remotes
git remote -v
# origin https://git.cleverthis.com/<your-username>/cleveragents-core.git (fetch)
# upstream https://git.cleverthis.com/cleveragents/cleveragents-core.git (fetch)
# 5. Keep your fork up to date before starting new work
git fetch upstream
git checkout master
git merge upstream/master
git push origin master
Branch Naming Conventions
All feature branches must be created from master and follow this naming pattern:
<type>/<short-description>
Where <type> matches the Conventional Changelog type of the primary change:
| Type | When to use |
|---|---|
feat |
New feature or capability |
fix |
Bug fix |
docs |
Documentation only |
refactor |
Code restructuring without behavior change |
test |
Adding or updating tests |
chore |
Build scripts, tooling, CI changes |
perf |
Performance improvement |
style |
Formatting, whitespace (no logic change) |
Examples:
git checkout -b feat/session-export-markdown
git checkout -b fix/tui-persona-switch-crash
git checkout -b docs/contributor-guide
git checkout -b refactor/actor-registry-cleanup
Rules:
- Use lowercase and hyphens only — no underscores, no spaces.
- Keep descriptions short (3–5 words).
- One logical change per branch. If you are fixing two separate bugs, use two branches.
- Never commit directly to
master.
Commit Message Format
All commits must follow the Conventional Changelog standard. This format drives automated changelog generation and makes history searchable.
Structure
<type>(<scope>): <short summary>
<body — what was done and why>
<footer — issue references>
Rules
- First line:
<type>(<scope>): <summary>— 72 characters max, imperative mood. - Blank line between subject and body.
- Body: Explain what and why, not how. Include trade-offs and rationale.
- Footer: Reference issues with
ISSUES CLOSED: #<n>orRefs: #<n>.
Examples
feat(cli): add session export markdown format
Implemented --format md flag for `agents session export`. Markdown
transcripts are human-readable and suitable for sharing outside the
platform. JSON export remains the default for round-trip fidelity.
ISSUES CLOSED: #312
fix(tui): prevent crash when switching persona with empty session
The PersonaSwitchOverlay called actor.get_context() before the session
was initialized, causing an AttributeError. Added a guard that returns
early when session is None.
ISSUES CLOSED: #298
Using Commitizen (recommended)
Commitizen guides you through the format interactively:
git add -p # stage changes selectively
git cz # interactive commit (replaces git commit)
Pre-commit Hooks
Pre-commit hooks run automatically on every git commit. They catch issues before they
reach CI. The full list of hooks is documented in
quality-automation.md.
Key hooks and what they check
| Hook | What it checks | Auto-fixes? |
|---|---|---|
ruff-format |
Code formatting (PEP 8 + Ruff style) | ✅ Yes |
ruff |
Linting rules (unused imports, style issues) | ✅ Partial |
pyright |
Static type errors in src/ |
❌ No |
bandit |
Security vulnerabilities | ❌ No |
vulture |
Unused / dead code | ❌ No |
commitizen |
Commit message format (commit-msg stage) | ❌ No |
check-yaml |
YAML syntax validity | ❌ No |
check-toml |
TOML syntax validity | ❌ No |
debug-statements |
Stray pdb / breakpoint() calls |
❌ No |
Running hooks manually
# Run all hooks on all files
pre-commit run --all-files
# Run a single hook
pre-commit run ruff-format --all-files
pre-commit run pyright --all-files
# Re-install hooks after pulling changes to .pre-commit-config.yaml
pre-commit install
pre-commit install --hook-type commit-msg
Tip: If a hook auto-fixes files, stage the fixes (
git add -p) and re-rungit commit. The hooks will pass on the second attempt.
Running the Test Suite
All tests are run through Nox — never invoke Behave or Robot Framework directly.
# Run everything (mirrors CI)
nox
# Individual sessions
nox -s format # Ruff auto-formatting
nox -s lint # Ruff linting
nox -s typecheck # Pyright type checking
nox -s unit_tests # Behave BDD unit tests
nox -s integration_tests # Robot Framework integration tests
nox -s coverage_report # Coverage report (must be ≥97%)
nox -s security_scan # Bandit + Semgrep + Vulture
nox -s dead_code # Vulture dead code detection
nox -s complexity # Radon complexity analysis
nox -s pre_commit # Run all pre-commit hooks via Nox
nox -s adr_compliance # Verify ADR compliance
Coverage requirement
Coverage must remain ≥ 97% at all times. If your change drops coverage:
# See exactly which lines are uncovered
nox -s coverage_report
Then add Behave scenarios to cover the missing lines (see Writing New Tests).
Using the mock AI provider
The test suite never calls external LLM APIs. The mock provider is activated
automatically when CLEVERAGENTS_TESTING_USE_MOCK_AI=true is set. The setup script
configures this for you, but you can also set it manually:
export CLEVERAGENTS_TESTING_USE_MOCK_AI=true
nox -s unit_tests
Writing New Tests
CleverAgents uses Behavior-Driven Development (BDD) exclusively for unit-level tests. Do not write xUnit-style tests (pytest, unittest). All new behavior must be expressed as Gherkin scenarios.
Where tests live
features/ # Behave BDD feature files and step definitions
*.feature # Gherkin scenarios
steps/ # Step definition modules
robot/ # Robot Framework integration suites
*.robot # Robot test files
Writing a Behave scenario
-
Find or create the feature file for the behavior you are testing.
- Check
features/for an existing file that covers the same area. - If none exists, create
features/<area>.feature.
- Check
-
Write the scenario in Gherkin:
Feature: Session export
Scenario: Export session as Markdown
Given an active session with three messages
When I run "agents session export --format md --output transcript.md"
Then the file "transcript.md" exists
And the file contains a Markdown heading with the session ID
-
Implement the step definitions in
features/steps/:- Check for an existing step file that covers the same behavior.
- Extend it rather than creating a duplicate.
- Name feature-specific step files after their feature (e.g.,
session_export_steps.py). - Shared steps go in clearly named reusable files.
-
Never commit a feature file without its step implementations. Every scenario must be fully implemented — no placeholder steps.
-
Run your new tests:
nox -s unit_tests
BDD best practices
- Write scenarios from the user's perspective, not the implementation's.
- One scenario per behavior — keep scenarios focused and independent.
- Use
Background:for shared setup that applies to all scenarios in a feature. - Prefer
Given/When/ThenoverAnd/Butfor the first step of each section. - Avoid testing implementation details — test observable behavior.
Code Style
CleverAgents uses Ruff for both formatting and linting. There is no separate Black or isort configuration — Ruff handles everything.
Formatting
# Auto-format all files
nox -s format
# Or run Ruff directly
ruff format src/ features/ tests/
Ruff formatting is enforced by pre-commit hooks and CI. If your editor supports it,
configure it to run ruff format on save.
Linting
# Run linting
nox -s lint
# Auto-fix safe issues
ruff check --fix src/
Key style rules
- File length: Keep files under 500 lines. Break large files into focused modules.
- Imports: Import only what you need — no wildcard imports (
from x import *). - Naming: Follow Python conventions —
snake_casefor functions/variables,PascalCasefor classes,UPPER_SNAKE_CASEfor constants. - No debug statements: Remove all
print(),pdb, andbreakpoint()calls before committing. - Docstrings: Public classes and functions must have docstrings.
Editor integration
Most editors can run Ruff automatically. For VS Code, install the Ruff extension and add to your settings:
{
"editor.formatOnSave": true,
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
}
Type Checking
CleverAgents uses Pyright in strict mode. All code in src/cleveragents/ must be
fully type-annotated with zero type errors.
# Run type checking
nox -s typecheck
# Or run Pyright directly
pyright src/cleveragents/
Rules
- Annotate everything: Every function signature, parameter, return type, and variable declaration must have explicit type annotations.
- No suppression: Never use
# type: ignore,cast()without justification, orAnyas a shortcut. If Pyright flags something, fix the root cause. - Generics: Use
TypeVar,Generic, andProtocolwhere appropriate rather than falling back toAny.
Common patterns
# Good — fully annotated
def export_session(session_id: str, format: Literal["json", "md"]) -> Path:
...
# Bad — missing annotations
def export_session(session_id, format):
...
If Pyright reports an error on code you believe is correct, check pyrightconfig.json
for the project's strict-mode configuration before assuming it is a false positive.
ADR Process
Architecture Decision Records (ADRs) capture significant architectural choices. Before making a structural change to the codebase, check whether an ADR is needed.
When to write an ADR
Write an ADR when your change:
- Introduces a new architectural pattern or layer
- Changes how a core abstraction (actor, tool, resource, session, etc.) works
- Adds a new external dependency that affects the architecture
- Makes a decision that is difficult or costly to reverse
- Resolves a significant trade-off between competing approaches
You do not need an ADR for:
- Bug fixes
- Documentation updates
- Adding new CLI flags or commands that fit existing patterns
- Refactoring that does not change behavior or interfaces
How to write an ADR
-
Read the ADR index at
docs/adr/index.mdto understand the format, front-matter fields, tier system, and status lifecycle. -
Assign the next sequential number. Check the existing ADRs and use the next available number (currently ADR-049 and above).
-
Create the file at
docs/adr/ADR-<NNN>-<kebab-case-title>.md. -
Write the front-matter with required fields:
--- adr_number: 49 title: "Your Decision Title" status_history: - ["2026-04-13", "Draft", "Your Name"] tier: 2 authors: ["Your Name"] superseded_by: null related_adrs: [] acceptance: votes_for: [] votes_against: [] abstentions: [] --- -
Write the body with these sections:
- Context — what problem or situation motivated this decision?
- Decision Drivers — the forces and constraints shaping the decision
- Decision — the choice made, stated clearly
- Consequences — positive and negative outcomes; trade-offs accepted
- Compliance — how to verify the decision is being followed
-
Propose the ADR by updating
status_historytoProposedand opening a PR. The ADR must be reviewed and accepted before implementation begins. -
After acceptance, update the specification (
docs/specification.md) to incorporate the decision. The specification is the authoritative source of truth.
Reference: See ADR-033 for an example of a well-structured ADR.
PR Submission Checklist
Before opening a Pull Request, verify every item below. PRs that do not meet these requirements will not be reviewed.
Code quality
- All pre-commit hooks pass (
pre-commit run --all-files) - All Nox sessions pass (
nox) - Test coverage is ≥ 97% (
nox -s coverage_report) - No Pyright type errors (
nox -s typecheck) - No Bandit security findings (
nox -s security_scan)
Commits
- Every commit follows Conventional Changelog format
- Every commit references its issue (
ISSUES CLOSED: #<n>orRefs: #<n>) - Each commit is atomic — one logical change, independently buildable
- No debug statements, temporary code, or unrelated edits in any commit
- History has been cleaned up with interactive rebase if needed
PR metadata
- PR description explains the change and its motivation
- PR includes a closing keyword for every linked issue (
Closes #<n>) - PR is assigned to the correct milestone (matching linked issues)
- PR has exactly one
Type/label (Type/Feature,Type/Bug,Type/Task, etc.) - Linked issues are added as Forgejo dependencies with the correct direction (PR blocks the issue; issue depends on the PR)
Documentation and housekeeping
- Relevant documentation updated alongside the code change
- Changelog updated with one entry per commit
CONTRIBUTORS.mdupdated if this is your first contribution- No build artifacts or install dependencies in any commit
- Version bumped if the change warrants it (new feature, bug fix in released version)
If an ADR was needed
- ADR written, proposed, and accepted before implementation
- Specification updated to reflect the accepted ADR
Review Process
What happens after you open a PR
-
Automated CI runs — all checks must pass before a reviewer looks at the code. Fix any failures before requesting review.
-
Initial feedback within 48 hours — a maintainer will review your PR and either approve it or request changes.
-
Address requested changes — push new commits (do not force-push to a PR under review unless asked). Each round of feedback should result in a new commit that addresses the specific requests.
-
Approval and merge — once all requirements are met (see CONTRIBUTING.md — Review and Merge Requirements), a maintainer will merge the PR.
-
Post-merge — move the linked issue(s) to
State/Completed.
Self-approval
Self-approval is permitted for automated bot PRs and for maintainers making routine changes. For all other contributions, at least one other person must approve.
What reviewers look for
Reviewers evaluate:
- Correctness — does the code do what it claims? Does it satisfy the acceptance criteria of the linked issue?
- Readability — is the code clear, well-named, and easy to follow?
- Test coverage — are the BDD scenarios adequate? Do they cover edge cases?
- Type safety — are all types annotated and correct?
- Security — does the code introduce any unsafe patterns?
- Style — does the code follow project conventions?
Responding to review comments
- Address every comment, even if just to explain why you disagree.
- If you disagree with a requested change, explain your reasoning — maintainers are open to discussion.
- Mark comments as resolved only after the change is made or the discussion is settled.
Further Reading
| Document | Description |
|---|---|
| CONTRIBUTING.md | Full contribution rules, code of conduct, versioning, issue management |
| quality-automation.md | Nox sessions, pre-commit hooks, CI pipeline, security scanning |
| automation-tracking.md | Automation tracking and quality metrics |
| docs/adr/index.md | ADR index, format reference, tier system, status lifecycle |
| docs/specification.md | Authoritative system specification |
| docs/architecture.md | Architecture overview |