Skip to main content

Contributing to ZeroClaw

Thanks for your interest in contributing to ZeroClaw! This guide will help you get started, whether you’re fixing a typo or building a new provider.

First-Time Contributors

Welcome — contributions of all sizes are valued. If this is your first contribution:
1

Find an issue

Look for issues labeled good first issue. These are scoped for newcomers and include context to get moving quickly.
2

Pick a scope

Good first contributions include:
  • Typo and documentation fixes
  • Test additions or improvements
  • Small bug fixes with clear reproduction steps
3

Follow the workflow

Fork → branch → change → test → PR:
4

Start with Track A

ZeroClaw uses three collaboration tracks (A/B/C) based on risk. First-time contributors should target Track A (docs, tests, chore) — these require lighter review and are the fastest path to a merged PR.
If you get stuck, open a draft PR early and ask questions in the description.

Development Setup

Quick Start

Pre-push Hook

The repo includes a pre-push hook in .githooks/ that enforces quality checks. Enable it with:
For opt-in strict lint passes:
To skip hooks during rapid iteration:
CI runs the same checks, so skipped hooks will be caught on the PR.

Collaboration Tracks (Risk-Based)

Every PR should map to one track to keep review throughput high:
When in doubt, choose the higher track.

Architecture: Trait-Based Pluggability

ZeroClaw’s architecture is built on traits — every subsystem is swappable. Contributing a new integration is as simple as implementing a trait and registering it.

How to Add Integrations

Adding a Provider

Create src/providers/your_provider.rs:
Register in src/providers/mod.rs:

Adding a Channel

Create src/channels/your_channel.rs:

Adding a Tool

Create src/tools/your_tool.rs:
See the examples directory for complete working examples of custom providers, channels, tools, and memory backends.

Code Naming Conventions

Use these defaults unless an existing subsystem pattern clearly overrides them:
  • Rust casing: modules/files snake_case, types/traits/enums PascalCase, functions/variables snake_case, constants SCREAMING_SNAKE_CASE
  • Domain-first naming: prefer DiscordChannel, SecurityPolicy, SqliteMemory over Manager, Util, Helper
  • Trait implementers: keep predictable suffixes (*Provider, *Channel, *Tool, *Memory)
  • Factory keys: lowercase and stable (openai, discord, shell)
  • Tests: behavior-oriented names (subject_expected_behavior)

Pull Request Checklist

  • PR template sections are completed (including security + rollback)
  • ./scripts/ci/rust_quality_gate.sh passes
  • cargo test --locked passes locally
  • New code has inline #[cfg(test)] tests
  • No new dependencies unless absolutely necessary
  • README updated if adding user-facing features
  • Follows code naming conventions and architecture boundary rules
  • No personal/sensitive data in code/docs/tests/fixtures
We use Conventional Commits:
Recommended scope keys: provider, channel, memory, security, runtime, ci, docs, tests
  • Minimal dependencies — every crate adds to binary size
  • Inline tests#[cfg(test)] mod tests {} at the bottom of each file
  • Trait-first — define the trait, then implement
  • Security by default — sandbox everything, allowlist, never blocklist
  • No unwrap in production code — use ?, anyhow, or thiserror

Reporting Issues

  • Bugs: Include OS, Rust version, steps to reproduce, expected vs actual
  • Features: Describe the use case, propose which trait to extend
  • Security: See SECURITY.md for responsible disclosure
  • Privacy: Redact/anonymize all personal data before posting logs/payloads

Resources

CONTRIBUTING.md

Full contributor guide with detailed workflows

Examples

Working code examples for all extension points

Architecture Docs

Deep dives into system design and patterns

Discussions

Ask questions and share ideas

License

By contributing, you agree that your contributions will be licensed under the MIT License.